summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/contentcapture/Android.bp3
-rw-r--r--apct-tests/perftests/contentcapture/AndroidManifest.xml5
-rw-r--r--apct-tests/perftests/contentcapture/AndroidTest.xml32
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java4
-rw-r--r--api/current.txt19
-rw-r--r--api/module-lib-current.txt1
-rwxr-xr-xapi/system-current.txt16
-rw-r--r--api/test-current.txt3
-rw-r--r--cmds/statsd/src/atoms.proto5
-rw-r--r--cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp2
-rw-r--r--config/boot-image-profile.txt29
-rw-r--r--config/preloaded-classes6
-rw-r--r--core/java/android/app/ActivityThread.java444
-rw-r--r--core/java/android/app/ApplicationLoaders.java4
-rw-r--r--core/java/android/app/ApplicationPackageManager.java3
-rw-r--r--core/java/android/app/ClientTransactionHandler.java54
-rw-r--r--core/java/android/app/IActivityManager.aidl2
-rw-r--r--core/java/android/app/LocalActivityManager.java31
-rw-r--r--core/java/android/app/Notification.java8
-rw-r--r--core/java/android/app/NotificationManager.java10
-rw-r--r--core/java/android/app/TEST_MAPPING27
-rw-r--r--core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java12
-rw-r--r--core/java/android/app/servertransaction/ActivityLifecycleItem.java2
-rw-r--r--core/java/android/app/servertransaction/ActivityRelaunchItem.java30
-rw-r--r--core/java/android/app/servertransaction/ActivityResultItem.java11
-rw-r--r--core/java/android/app/servertransaction/ActivityTransactionItem.java69
-rw-r--r--core/java/android/app/servertransaction/DestroyActivityItem.java8
-rw-r--r--core/java/android/app/servertransaction/EnterPipRequestedItem.java8
-rw-r--r--core/java/android/app/servertransaction/LaunchActivityItem.java3
-rw-r--r--core/java/android/app/servertransaction/MoveToDisplayItem.java13
-rw-r--r--core/java/android/app/servertransaction/NewIntentItem.java11
-rw-r--r--core/java/android/app/servertransaction/PauseActivityItem.java9
-rw-r--r--core/java/android/app/servertransaction/ResumeActivityItem.java8
-rw-r--r--core/java/android/app/servertransaction/StartActivityItem.java9
-rw-r--r--core/java/android/app/servertransaction/StopActivityItem.java8
-rw-r--r--core/java/android/app/servertransaction/TopResumedActivityChangeItem.java26
-rw-r--r--core/java/android/app/servertransaction/TransactionExecutor.java12
-rw-r--r--core/java/android/app/slice/SliceProvider.java5
-rw-r--r--core/java/android/hardware/face/FaceManager.java49
-rw-r--r--core/java/android/hardware/face/IFaceServiceReceiver.aidl2
-rw-r--r--core/java/android/net/NetworkTemplate.java4
-rwxr-xr-xcore/java/android/os/Build.java14
-rw-r--r--core/java/android/permission/PermissionControllerService.java11
-rw-r--r--core/java/android/permission/PermissionManager.java27
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/java/android/view/ImeInsetsSourceConsumer.java10
-rw-r--r--core/java/android/view/NotificationHeaderView.java24
-rw-r--r--core/java/android/view/inputmethod/BaseInputConnection.java20
-rw-r--r--core/java/android/webkit/UserPackage.java2
-rw-r--r--core/java/com/android/internal/util/Preconditions.java26
-rw-r--r--core/java/com/android/internal/widget/ConversationLayout.java48
-rw-r--r--core/jni/android_media_AudioDeviceAttributes.cpp2
-rw-r--r--core/jni/android_media_AudioSystem.cpp85
-rw-r--r--core/proto/android/app/settings_enums.proto35
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--core/res/res/layout/notification_template_header.xml37
-rw-r--r--core/res/res/values/cross_profile_apps.xml2
-rw-r--r--core/res/res/xml/power_profile.xml2
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityThreadTest.java56
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java66
-rw-r--r--core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java10
-rw-r--r--drm/java/android/drm/DrmManagerClient.java2
-rw-r--r--libs/hostgraphics/Android.bp6
-rw-r--r--libs/hwui/renderthread/EglManager.cpp9
-rwxr-xr-xmedia/java/android/media/AudioManager.java173
-rw-r--r--media/java/android/media/AudioSystem.java55
-rwxr-xr-xmedia/java/android/media/IAudioService.aidl14
-rw-r--r--media/java/android/media/IStrategyPreferredDevicesDispatcher.aidl (renamed from media/java/android/media/IStrategyPreferredDeviceDispatcher.aidl)6
-rw-r--r--media/java/android/service/media/MediaBrowserService.java11
-rw-r--r--media/jni/audioeffect/android_media_AudioEffect.cpp2
-rw-r--r--non-updatable-api/current.txt19
-rw-r--r--non-updatable-api/module-lib-current.txt1
-rw-r--r--non-updatable-api/system-current.txt16
-rw-r--r--packages/CarSystemUI/proguard.flags2
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarGlobalRootComponent.java (renamed from packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java)14
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java38
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java6
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java23
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java4
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java8
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java9
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java2
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java5
-rw-r--r--packages/SystemUI/proguard.flags8
-rw-r--r--packages/SystemUI/res/layout/back.xml2
-rw-r--r--packages/SystemUI/res/layout/contextual.xml4
-rw-r--r--packages/SystemUI/res/layout/custom_key.xml2
-rw-r--r--packages/SystemUI/res/layout/home.xml2
-rw-r--r--packages/SystemUI/res/layout/home_handle.xml2
-rw-r--r--packages/SystemUI/res/layout/ime_switcher.xml2
-rw-r--r--packages/SystemUI/res/layout/menu_ime.xml6
-rw-r--r--packages/SystemUI/res/layout/navigation_bar.xml7
-rw-r--r--packages/SystemUI/res/layout/navigation_bar_window.xml4
-rw-r--r--packages/SystemUI/res/layout/navigation_layout.xml4
-rw-r--r--packages/SystemUI/res/layout/navigation_layout_vertical.xml8
-rw-r--r--packages/SystemUI/res/layout/recent_apps.xml2
-rw-r--r--packages/SystemUI/res/layout/rotate_suggestion.xml2
-rw-r--r--packages/SystemUI/res/values/config.xml6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java10
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/DemoMode.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java50
-rw-r--r--packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIApplication.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIFactory.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistHandleViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java192
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java (renamed from packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java)47
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SysUISingleton.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/WMModule.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/WMSingleton.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/demomode/DemoMode.java70
-rw-r--r--packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt109
-rw-r--r--packages/SystemUI/src/com/android/systemui/demomode/DemoModeCommandReceiver.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt249
-rw-r--r--packages/SystemUI/src/com/android/systemui/demomode/dagger/DemoModeModule.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt131
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaData.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java)385
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java396
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFrame.java)20
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java)29
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java)10
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java)39
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationModeController.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/RotationButton.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java)8
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java)17
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java)25
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonInterface.java)6
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java)9
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java)21
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java)8
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java)6
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java)6
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java)5
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java)18
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/buttons/RotationContextButton.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java)11
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java)8
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/FloatingRotationButton.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java)12
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java)5
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickswitchOrientedNavHandle.java)8
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/RegionSamplingHelper.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java)16
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSettingsUtil.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/onehanded/OneHandedUI.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java248
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java83
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt90
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManager.kt240
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RootNodeController.kt58
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt221
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManagerLogger.kt)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt88
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java214
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java130
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java183
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AppButtonData.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java54
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java147
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java158
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java81
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java56
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverControllerImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java397
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockControllerImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java110
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java79
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java (renamed from packages/SystemUI/src/com/android/systemui/tv/TvSystemUIRootComponent.java)14
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponent.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java166
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java79
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/Utils.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java82
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt52
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt122
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarButtonTest.java)6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java)66
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarInflaterViewTest.java)8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarRotationContextTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java)8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java)220
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java)23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyButtonViewTest.java)31
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java)10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java)19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedSettingsUtilTest.java18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedUITest.java90
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java145
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.java304
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java230
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java26
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java9
-rw-r--r--packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java4
-rw-r--r--packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java4
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java4
-rw-r--r--packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java4
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java49
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerService.java2
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerService.java17
-rw-r--r--services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java7
-rw-r--r--services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java2
-rw-r--r--services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java26
-rw-r--r--services/backup/java/com/android/server/backup/utils/TarBackupReader.java2
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java2
-rw-r--r--services/core/java/android/os/UserManagerInternal.java3
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java2
-rw-r--r--services/core/java/com/android/server/IpSecService.java2
-rw-r--r--services/core/java/com/android/server/ServiceWatcher.java43
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java2
-rw-r--r--services/core/java/com/android/server/SystemService.java73
-rw-r--r--services/core/java/com/android/server/SystemServiceManager.java50
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java25
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java621
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java2
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java3
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java11
-rw-r--r--services/core/java/com/android/server/am/UidObserverController.java460
-rw-r--r--services/core/java/com/android/server/am/UserController.java4
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java4
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java50
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java57
-rwxr-xr-xservices/core/java/com/android/server/audio/AudioService.java144
-rw-r--r--services/core/java/com/android/server/audio/AudioSystemAdapter.java19
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java40
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java22
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java15
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/EnrollClient.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java56
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/InternalEnumerateClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/Interruptable.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/RemovalClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/RevokeChallengeClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/Face10.java84
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java16
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceInternalEnumerateClient.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceRemovalClient.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java12
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java23
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticationClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintDetectClient.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintEnrollClient.java4
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintInternalEnumerateClient.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintRemovalClient.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUpdateActiveUserClient.java15
-rw-r--r--services/core/java/com/android/server/connectivity/PermissionMonitor.java111
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java73
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java2
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java7
-rw-r--r--services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java2
-rw-r--r--services/core/java/com/android/server/location/LocationProviderManager.java6
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsStorage.java2
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java12
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java39
-rw-r--r--services/core/java/com/android/server/media/MediaSessionStack.java23
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java118
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java3
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java83
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java5
-rw-r--r--services/core/java/com/android/server/pm/Settings.java3
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java37
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java19
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java2
-rw-r--r--services/core/java/com/android/server/policy/PermissionPolicyService.java10
-rw-r--r--services/core/java/com/android/server/power/ThermalManagerService.java2
-rwxr-xr-xservices/core/java/com/android/server/tv/TvInputManagerService.java11
-rw-r--r--services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java41
-rw-r--r--services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java107
-rw-r--r--services/core/java/com/android/server/uri/UriGrantsManagerInternal.java23
-rw-r--r--services/core/java/com/android/server/uri/UriGrantsManagerService.java19
-rw-r--r--services/core/java/com/android/server/uri/UriPermissionOwner.java38
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java14
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java7
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java22
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java4
-rw-r--r--services/core/java/com/android/server/wm/Task.java19
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotController.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java22
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java8
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowToken.java20
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/CallerIdentity.java61
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java55
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java60
-rw-r--r--services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java278
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java16
-rw-r--r--services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java303
-rw-r--r--services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java8
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java15
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java36
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java15
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java31
-rwxr-xr-xtelecomm/java/android/telecom/ConnectionService.java36
-rw-r--r--telecomm/java/android/telecom/RemoteConference.java24
-rw-r--r--telecomm/java/android/telecom/RemoteConnection.java25
-rw-r--r--telecomm/java/android/telecom/RemoteConnectionManager.java31
-rw-r--r--telecomm/java/android/telecom/RemoteConnectionService.java34
-rw-r--r--telephony/common/com/android/internal/telephony/CarrierAppUtils.java11
-rw-r--r--telephony/java/android/telephony/SmsManager.java14
-rw-r--r--telephony/java/android/telephony/ims/ImsConferenceState.java6
-rw-r--r--tests/RollbackTest/README.txt4
-rw-r--r--tests/StagedInstallTest/Android.bp3
-rw-r--r--tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java23
-rw-r--r--tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java55
-rw-r--r--tests/net/common/java/android/net/DhcpInfoTest.java4
-rw-r--r--tests/net/common/java/android/net/IpPrefixTest.java8
-rw-r--r--tests/net/common/java/android/net/LinkAddressTest.java8
-rw-r--r--tests/net/common/java/android/net/LinkPropertiesTest.java6
-rw-r--r--tests/net/common/java/android/net/NetworkCapabilitiesTest.java4
-rw-r--r--tests/net/common/java/android/net/RouteInfoTest.java8
-rw-r--r--tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java2
-rw-r--r--tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt2
-rw-r--r--tests/net/integration/util/com/android/server/NetworkAgentWrapper.java6
-rw-r--r--tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java2
-rw-r--r--tests/net/java/android/net/IpSecConfigTest.java4
-rw-r--r--tests/net/java/android/net/TcpKeepalivePacketDataTest.java2
-rw-r--r--tests/net/java/android/net/TelephonyNetworkSpecifierTest.java2
-rw-r--r--tests/net/java/android/net/nsd/NsdManagerTest.java6
-rw-r--r--tests/net/java/com/android/internal/net/VpnProfileTest.java2
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java48
-rw-r--r--tests/net/java/com/android/server/connectivity/DnsManagerTest.java6
-rw-r--r--tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java2
-rw-r--r--tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java91
-rw-r--r--tests/net/java/com/android/server/connectivity/VpnTest.java22
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java2
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsObserversTest.java6
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsServiceTest.java14
-rwxr-xr-xtools/hiddenapi/generate_hiddenapi_lists.py56
-rwxr-xr-xtools/hiddenapi/generate_hiddenapi_lists_test.py17
-rw-r--r--wifi/java/android/net/wifi/SoftApConfiguration.java1
-rw-r--r--wifi/java/android/net/wifi/hotspot2/pps/Credential.java13
-rw-r--r--wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java4
-rw-r--r--wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl2
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pManager.java25
-rw-r--r--wifi/tests/src/android/net/wifi/FakeKeys.java29
-rw-r--r--wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java17
-rw-r--r--wifi/tests/src/android/net/wifi/WifiClientTest.java4
-rw-r--r--wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java192
-rw-r--r--wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java23
469 files changed, 9059 insertions, 5921 deletions
diff --git a/apct-tests/perftests/contentcapture/Android.bp b/apct-tests/perftests/contentcapture/Android.bp
index 66d7348008ab..19a66ad9f27b 100644
--- a/apct-tests/perftests/contentcapture/Android.bp
+++ b/apct-tests/perftests/contentcapture/Android.bp
@@ -20,9 +20,10 @@ android_test {
"androidx.test.rules",
"androidx.annotation_annotation",
"apct-perftests-utils",
- "collector-device-lib-platform",
+ "collector-device-lib",
"compatibility-device-util-axt",
],
platform_apis: true,
test_suites: ["device-tests"],
+ data: [":perfetto_artifacts"],
}
diff --git a/apct-tests/perftests/contentcapture/AndroidManifest.xml b/apct-tests/perftests/contentcapture/AndroidManifest.xml
index ee5577f265fa..80957c78abf3 100644
--- a/apct-tests/perftests/contentcapture/AndroidManifest.xml
+++ b/apct-tests/perftests/contentcapture/AndroidManifest.xml
@@ -16,11 +16,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.perftests.contentcapture">
- <uses-sdk android:targetSdkVersion="28" />
-
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.REAL_GET_TASKS" />
-
<application>
<uses-library android:name="android.test.runner" />
<activity android:name="android.view.contentcapture.CustomTestActivity"
diff --git a/apct-tests/perftests/contentcapture/AndroidTest.xml b/apct-tests/perftests/contentcapture/AndroidTest.xml
index d2386bb1efea..d8e0a17d3935 100644
--- a/apct-tests/perftests/contentcapture/AndroidTest.xml
+++ b/apct-tests/perftests/contentcapture/AndroidTest.xml
@@ -21,7 +21,39 @@
<option name="test-file-name" value="ContentCapturePerfTests.apk" />
</target_preparer>
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file" key="trace_config_detailed.textproto" value="/data/misc/perfetto-traces/trace_config.textproto" />
+ </target_preparer>
+
+ <!-- Needed for pulling the collected trace config on to the host -->
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="pull-pattern-keys" value="perfetto_file_path" />
+ </metrics_collector>
+
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false" />
+
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.perftests.contentcapture" />
+
+ <!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
+ <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener" />
+ <!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
+ <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
+
+ <!-- ProcLoadListener related arguments -->
+ <!-- Wait for device last minute threshold to reach 3 with 2 minute timeout before starting the test run -->
+ <option name="instrumentation-arg" key="procload-collector:per_run" value="true" />
+ <option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
+ <option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
+ <option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
+
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
+ <option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
+
+ <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
</test>
</configuration>
diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java b/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java
index c276ae1fe45e..6e644ffb8b27 100644
--- a/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java
+++ b/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java
@@ -168,7 +168,9 @@ public final class SearchSpec {
/** Sets the maximum number of results to retrieve from the query */
@NonNull
public SearchSpec.Builder setNumToRetrieve(int numToRetrieve) {
- mResultSpecBuilder.setNumToRetrieve(numToRetrieve);
+ // Just retrieve everything in one page.
+ // TODO(b/152359656): Realign these two apis properly.
+ mResultSpecBuilder.setNumPerPage(numToRetrieve);
return this;
}
diff --git a/api/current.txt b/api/current.txt
index 69700f3b0a60..532c3d938334 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -45976,7 +45976,9 @@ package android.telecom {
method public final void addExistingConnection(android.telecom.PhoneAccountHandle, android.telecom.Connection);
method public final void conferenceRemoteConnections(android.telecom.RemoteConnection, android.telecom.RemoteConnection);
method public final void connectionServiceFocusReleased();
+ method @Nullable public final android.telecom.RemoteConference createRemoteIncomingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
method public final android.telecom.RemoteConnection createRemoteIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+ method @Nullable public final android.telecom.RemoteConference createRemoteOutgoingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
method public final android.telecom.RemoteConnection createRemoteOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public final java.util.Collection<android.telecom.Conference> getAllConferences();
method public final java.util.Collection<android.telecom.Connection> getAllConnections();
@@ -46207,6 +46209,7 @@ package android.telecom {
public final class RemoteConnection {
method public void abort();
+ method public void addConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
method public void answer();
method public void disconnect();
method public android.net.Uri getAddress();
@@ -65724,7 +65727,7 @@ package java.lang.reflect {
package java.math {
- public class BigDecimal extends java.lang.Number implements java.lang.Comparable<java.math.BigDecimal> java.io.Serializable {
+ public class BigDecimal extends java.lang.Number implements java.lang.Comparable<java.math.BigDecimal> {
ctor public BigDecimal(char[], int, int);
ctor public BigDecimal(char[], int, int, java.math.MathContext);
ctor public BigDecimal(char[]);
@@ -65811,19 +65814,20 @@ package java.math {
field public static final java.math.BigDecimal ZERO;
}
- public class BigInteger extends java.lang.Number implements java.lang.Comparable<java.math.BigInteger> java.io.Serializable {
+ public class BigInteger extends java.lang.Number implements java.lang.Comparable<java.math.BigInteger> {
+ ctor public BigInteger(byte[]);
+ ctor public BigInteger(int, byte[]);
+ ctor public BigInteger(@NonNull String, int);
+ ctor public BigInteger(@NonNull String);
ctor public BigInteger(int, @NonNull java.util.Random);
ctor public BigInteger(int, int, @NonNull java.util.Random);
- ctor public BigInteger(@NonNull String);
- ctor public BigInteger(@NonNull String, int);
- ctor public BigInteger(int, byte[]);
- ctor public BigInteger(byte[]);
method @NonNull public java.math.BigInteger abs();
method @NonNull public java.math.BigInteger add(@NonNull java.math.BigInteger);
method @NonNull public java.math.BigInteger and(@NonNull java.math.BigInteger);
method @NonNull public java.math.BigInteger andNot(@NonNull java.math.BigInteger);
method public int bitCount();
method public int bitLength();
+ method public byte byteValueExact();
method @NonNull public java.math.BigInteger clearBit(int);
method public int compareTo(@NonNull java.math.BigInteger);
method @NonNull public java.math.BigInteger divide(@NonNull java.math.BigInteger);
@@ -65834,8 +65838,10 @@ package java.math {
method @NonNull public java.math.BigInteger gcd(@NonNull java.math.BigInteger);
method public int getLowestSetBit();
method public int intValue();
+ method public int intValueExact();
method public boolean isProbablePrime(int);
method public long longValue();
+ method public long longValueExact();
method @NonNull public java.math.BigInteger max(@NonNull java.math.BigInteger);
method @NonNull public java.math.BigInteger min(@NonNull java.math.BigInteger);
method @NonNull public java.math.BigInteger mod(@NonNull java.math.BigInteger);
@@ -65852,6 +65858,7 @@ package java.math {
method @NonNull public java.math.BigInteger setBit(int);
method @NonNull public java.math.BigInteger shiftLeft(int);
method @NonNull public java.math.BigInteger shiftRight(int);
+ method public short shortValueExact();
method public int signum();
method @NonNull public java.math.BigInteger subtract(@NonNull java.math.BigInteger);
method public boolean testBit(int);
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
index b587ea1f3b74..7cd8a628c9fc 100644
--- a/api/module-lib-current.txt
+++ b/api/module-lib-current.txt
@@ -7,6 +7,7 @@ package android.app {
public class NotificationManager {
method public boolean hasEnabledNotificationListener(@NonNull String, @NonNull android.os.UserHandle);
+ field public static final String ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED = "android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED";
}
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 721523c95ecb..ea16238316ac 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4196,7 +4196,8 @@ package android.media {
public class AudioManager {
method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
- method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException;
+ method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException;
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener) throws java.lang.SecurityException;
method public void clearAudioServerStateCallback();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
@@ -4208,13 +4209,15 @@ package android.media {
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAttributes getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages();
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method public boolean isAudioServerRunning();
method public boolean isHdmiSystemAudioSupported();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
method public void registerVolumeGroupCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.VolumeGroupCallback);
- method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean removePreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int, android.media.audiopolicy.AudioPolicy) throws java.lang.IllegalArgumentException;
@@ -4224,6 +4227,7 @@ package android.media {
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setVolumeIndexForAttributes(@NonNull android.media.AudioAttributes, int, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
@@ -4247,8 +4251,12 @@ package android.media {
method public void onAudioServerUp();
}
- public static interface AudioManager.OnPreferredDeviceForStrategyChangedListener {
- method public void onPreferredDeviceForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @Nullable android.media.AudioDeviceAttributes);
+ @Deprecated public static interface AudioManager.OnPreferredDeviceForStrategyChangedListener {
+ method @Deprecated public void onPreferredDeviceForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @Nullable android.media.AudioDeviceAttributes);
+ }
+
+ public static interface AudioManager.OnPreferredDevicesForStrategyChangedListener {
+ method public void onPreferredDevicesForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
}
public abstract static class AudioManager.VolumeGroupCallback {
diff --git a/api/test-current.txt b/api/test-current.txt
index 3332525a6647..10a367fa9267 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1780,6 +1780,9 @@ package android.media {
method public static float getMasterBalance();
method public static final int getNumStreamTypes();
method public static int setMasterBalance(float);
+ field public static final int DEVICE_ROLE_DISABLED = 2; // 0x2
+ field public static final int DEVICE_ROLE_NONE = 0; // 0x0
+ field public static final int DEVICE_ROLE_PREFERRED = 1; // 0x1
field public static final int STREAM_DEFAULT = -1; // 0xffffffff
}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index c95f4c07f86c..6b335ee1b923 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -4434,15 +4434,12 @@ message PrivacyIndicatorsInteracted {
UNKNOWN = 0;
CHIP_VIEWED = 1;
CHIP_CLICKED = 2;
- DIALOG_PRIVACY_SETTINGS = 3;
+ reserved 3; // Used only in beta builds, never shipped
DIALOG_DISMISS = 4;
DIALOG_LINE_ITEM = 5;
}
optional Type type = 1 [(state_field_option).exclusive_state = true];
-
- // Used if the type is LINE_ITEM
- optional string package_name = 2;
}
/**
diff --git a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
index 52ef95d19cdc..9d3943fe8260 100644
--- a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
@@ -148,8 +148,6 @@ bool handleMetricWithConditions(
ALOGW("cannot find Predicate \"%lld\" in the config", (long long)link.condition());
return false;
}
- allConditionTrackers[condition_it->second]->setSliced(true);
- allConditionTrackers[it->second]->setSliced(true);
}
conditionIndex = condition_it->second;
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index ab2f42b97e3b..f43bd2bd61b9 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -33629,6 +33629,35 @@ HSPLjava/math/BigInteger;-><init>([B)V
HSPLjava/math/BigInteger;->abs()Ljava/math/BigInteger;
HSPLjava/math/BigInteger;->add(Ljava/math/BigInteger;)Ljava/math/BigInteger;
HSPLjava/math/BigInteger;->bitLength()I
+#Temporary manual additions to avoid slowing tests down too much
+#Carefully positioned for clean merge
+HSPLjava/math/BigInteger;->add([IJ)[I
+HSPLjava/math/BigInteger;->add([I[I)[I
+HSPLjava/math/BigInteger;->subtract([IJ)[I
+HSPLjava/math/BigInteger;->subtract([I[I)[I
+HSPLjava/math/BigInteger;->jacobiSymbol(ILjava/math/BigInteger;)I
+HSPLjava/math/BigInteger;->lucasLehmerSequence(ILjava/math/BigInteger;Ljava/math/BigInteger;)Ljava/math/BigInteger;
+HSPLjava/math/BigInteger;->multiplyToLen([II[II[I)[I
+HSPLjava/math/MutableBigInteger;->add(Ljava/math/MutableBigInteger;)V
+HSPLjava/math/MutableBigInteger;->addShifted(Ljava/math/MutableBigInteger;)V
+HSPLjava/math/MutableBigInteger;->subtract(Ljava/math/MutableBigInteger;)V
+HSPLjava/math/MutableBigInteger;->difference(Ljava/math/MutableBigInteger;)V
+HSPLjava/math/MutableBigInteger;->divideKnuth(Ljava/math/MutableBigInteger;Ljava/math/MutableBigInteger;Z)Ljava/math/MutableBigInteger;
+HSPLjava/math/MutableBigInteger;->divideMagnitude(Ljava/math/MutableBigInteger;Ljava/math/MutableBigInteger;Z)Ljava/math/MutableBigInteger;
+HSPLjava/math/MutableBigInteger;->divideLongMagnitude(JLjava/math/MutableBigInteger;)Ljava/math/MutableBigInteger;
+HSPLjava/math/MutableBigInteger;->divideOneWord(ILjava/math/MutableBigInteger;)I
+HSPLjava/math/MutableBigInteger;->divadd([I[II)I
+HSPLjava/math/MutableBigInteger;->mulsub([I[IIII)I
+HSPLjava/math/MutableBigInteger;->mulsubBorrow([I[IIII)I
+HSPLjava/math/MutableBigInteger;->copyAndShift([III[III)V
+HSPLjava/math/MutableBigInteger;->multiply(Ljava/math/MutableBigInteger;Ljava/math/MutableBigInteger;)V
+HSPLjava/math/MutableBigInteger;->mul(ILjava/math/MutableBigInteger;)V
+HSPLjava/math/MutableBigInteger;->multiply(ILjava/math/MutableBigInteger;)V
+HSPLjava/math/MutableBigInteger;->primitiveRightShift(I)I
+HSPLjava/math/MutableBigInteger;->primitiveLeftShift(I)I
+HSPLjava/math/MutableBigInteger;->binaryGCD(Ljava/math/MutableBigInteger;)Ljava/math/MutableBigInteger;
+HSPLjava/math/MutableBigInteger;->binaryGCD(II)I
+#End of maual additions
HSPLjava/math/BigInteger;->compareTo(Ljava/math/BigInteger;)I
HSPLjava/math/BigInteger;->divide(Ljava/math/BigInteger;)Ljava/math/BigInteger;
HSPLjava/math/BigInteger;->divideAndRemainder(Ljava/math/BigInteger;)[Ljava/math/BigInteger;
diff --git a/config/preloaded-classes b/config/preloaded-classes
index e43c7d42868c..f56656b69ec4 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -3709,9 +3709,9 @@ android.media.IRemoteVolumeObserver
android.media.IRingtonePlayer$Stub$Proxy
android.media.IRingtonePlayer$Stub
android.media.IRingtonePlayer
-android.media.IStrategyPreferredDeviceDispatcher$Stub$Proxy
-android.media.IStrategyPreferredDeviceDispatcher$Stub
-android.media.IStrategyPreferredDeviceDispatcher
+android.media.IStrategyPreferredDevicesDispatcher$Stub$Proxy
+android.media.IStrategyPreferredDevicesDispatcher$Stub
+android.media.IStrategyPreferredDevicesDispatcher
android.media.IVolumeController$Stub$Proxy
android.media.IVolumeController$Stub
android.media.IVolumeController
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d67b98620f37..267b81823688 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -614,7 +614,7 @@ public final class ActivityThread extends ClientTransactionHandler {
throw new IllegalStateException(
"Received config update for non-existing activity");
}
- activity.mMainThread.handleActivityConfigurationChanged(token, overrideConfig,
+ activity.mMainThread.handleActivityConfigurationChanged(this, overrideConfig,
newDisplayId);
};
}
@@ -3475,13 +3475,9 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleStartActivity(IBinder token, PendingTransactionActions pendingActions) {
- final ActivityClientRecord r = mActivities.get(token);
+ public void handleStartActivity(ActivityClientRecord r,
+ PendingTransactionActions pendingActions) {
final Activity activity = r.activity;
- if (r.activity == null) {
- // TODO(lifecycler): What do we do in this case?
- return;
- }
if (!r.stopped) {
throw new IllegalStateException("Can't start activity that is not stopped.");
}
@@ -3687,12 +3683,7 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleNewIntent(IBinder token, List<ReferrerIntent> intents) {
- final ActivityClientRecord r = mActivities.get(token);
- if (r == null) {
- return;
- }
-
+ public void handleNewIntent(ActivityClientRecord r, List<ReferrerIntent> intents) {
checkAndBlockForNetworkAccess();
deliverNewIntents(r, intents);
}
@@ -3881,13 +3872,7 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handlePictureInPictureRequested(IBinder token) {
- final ActivityClientRecord r = mActivities.get(token);
- if (r == null) {
- Log.w(TAG, "Activity to request PIP to no longer exists");
- return;
- }
-
+ public void handlePictureInPictureRequested(ActivityClientRecord r) {
final boolean receivedByApp = r.activity.onPictureInPictureRequested();
if (!receivedByApp) {
// Previous recommendation was for apps to enter picture-in-picture in
@@ -4417,22 +4402,21 @@ public final class ActivityThread extends ClientTransactionHandler {
/**
* Resume the activity.
- * @param token Target activity token.
+ * @param r Target activity record.
* @param finalStateRequest Flag indicating if this is part of final state resolution for a
* transaction.
* @param reason Reason for performing the action.
*
- * @return The {@link ActivityClientRecord} that was resumed, {@code null} otherwise.
+ * @return {@code true} that was resumed, {@code false} otherwise.
*/
@VisibleForTesting
- public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
+ public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
String reason) {
- final ActivityClientRecord r = mActivities.get(token);
if (localLOGV) {
Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished);
}
- if (r == null || r.activity.mFinished) {
- return null;
+ if (r.activity.mFinished) {
+ return false;
}
if (r.getLifecycleState() == ON_RESUME) {
if (!finalStateRequest) {
@@ -4446,7 +4430,7 @@ public final class ActivityThread extends ClientTransactionHandler {
// handle two resume requests for the final state. For cases other than this
// one, we don't expect it to happen.
}
- return null;
+ return false;
}
if (finalStateRequest) {
r.hideForNow = false;
@@ -4477,7 +4461,7 @@ public final class ActivityThread extends ClientTransactionHandler {
+ r.intent.getComponent().toShortString() + ": " + e.toString(), e);
}
}
- return r;
+ return true;
}
static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
@@ -4498,20 +4482,19 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
- String reason) {
+ public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
+ boolean isForward, String reason) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
// TODO Push resumeArgs into the activity for consideration
- final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
- if (r == null) {
- // We didn't actually resume the activity, so skipping any follow-up actions.
+ // skip below steps for double-resume and r.mFinish = true case.
+ if (!performResumeActivity(r, finalStateRequest, reason)) {
return;
}
- if (mActivitiesToBeDestroyed.containsKey(token)) {
+ if (mActivitiesToBeDestroyed.containsKey(r.token)) {
// Although the activity is resumed, it is going to be destroyed. So the following
// UI operations are unnecessary and also prevents exception because its token may
// be gone that window manager cannot recognize it. All necessary cleanup actions
@@ -4629,13 +4612,8 @@ public final class ActivityThread extends ClientTransactionHandler {
@Override
- public void handleTopResumedActivityChanged(IBinder token, boolean onTop, String reason) {
- ActivityClientRecord r = mActivities.get(token);
- if (r == null || r.activity == null) {
- Slog.w(TAG, "Not found target activity to report position change for token: " + token);
- return;
- }
-
+ public void handleTopResumedActivityChanged(ActivityClientRecord r, boolean onTop,
+ String reason) {
if (DEBUG_ORDER) {
Slog.d(TAG, "Received position change to top: " + onTop + " for activity: " + r);
}
@@ -4668,23 +4646,20 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
+ public void handlePauseActivity(ActivityClientRecord r, boolean finished, boolean userLeaving,
int configChanges, PendingTransactionActions pendingActions, String reason) {
- ActivityClientRecord r = mActivities.get(token);
- if (r != null) {
- if (userLeaving) {
- performUserLeavingActivity(r);
- }
+ if (userLeaving) {
+ performUserLeavingActivity(r);
+ }
- r.activity.mConfigChangeFlags |= configChanges;
- performPauseActivity(r, finished, reason, pendingActions);
+ r.activity.mConfigChangeFlags |= configChanges;
+ performPauseActivity(r, finished, reason, pendingActions);
- // Make sure any pending writes are now committed.
- if (r.isPreHoneycomb()) {
- QueuedWork.waitToFinish();
- }
- mSomeActivitiesChanged = true;
+ // Make sure any pending writes are now committed.
+ if (r.isPreHoneycomb()) {
+ QueuedWork.waitToFinish();
}
+ mSomeActivitiesChanged = true;
}
final void performUserLeavingActivity(ActivityClientRecord r) {
@@ -4781,8 +4756,11 @@ public final class ActivityThread extends ClientTransactionHandler {
r.setState(ON_PAUSE);
}
+ // TODO(b/127877792): Make LocalActivityManager call performStopActivityInner. We cannot do this
+ // since it's a high usage hidden API.
/** Called from {@link LocalActivityManager}. */
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 127877792,
+ publicAlternatives = "{@code N/A}")
final void performStopActivity(IBinder token, boolean saveState, String reason) {
ActivityClientRecord r = mActivities.get(token);
performStopActivityInner(r, null /* stopInfo */, saveState, false /* finalStateRequest */,
@@ -4823,39 +4801,37 @@ public final class ActivityThread extends ClientTransactionHandler {
private void performStopActivityInner(ActivityClientRecord r, StopInfo info,
boolean saveState, boolean finalStateRequest, String reason) {
if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
- if (r != null) {
- if (r.stopped) {
- if (r.activity.mFinished) {
- // If we are finishing, we won't call onResume() in certain
- // cases. So here we likewise don't want to call onStop()
- // if the activity isn't resumed.
- return;
- }
- if (!finalStateRequest) {
- final RuntimeException e = new RuntimeException(
- "Performing stop of activity that is already stopped: "
- + r.intent.getComponent().toShortString());
- Slog.e(TAG, e.getMessage(), e);
- Slog.e(TAG, r.getStateString());
- }
+ if (r.stopped) {
+ if (r.activity.mFinished) {
+ // If we are finishing, we won't call onResume() in certain
+ // cases. So here we likewise don't want to call onStop()
+ // if the activity isn't resumed.
+ return;
+ }
+ if (!finalStateRequest) {
+ final RuntimeException e = new RuntimeException(
+ "Performing stop of activity that is already stopped: "
+ + r.intent.getComponent().toShortString());
+ Slog.e(TAG, e.getMessage(), e);
+ Slog.e(TAG, r.getStateString());
}
+ }
- // One must first be paused before stopped...
- performPauseActivityIfNeeded(r, reason);
+ // One must first be paused before stopped...
+ performPauseActivityIfNeeded(r, reason);
- if (info != null) {
- try {
- // First create a thumbnail for the activity...
- // For now, don't create the thumbnail here; we are
- // doing that by doing a screen snapshot.
- info.setDescription(r.activity.onCreateDescription());
- } catch (Exception e) {
- if (!mInstrumentation.onException(r.activity, e)) {
- throw new RuntimeException(
- "Unable to save state of activity "
- + r.intent.getComponent().toShortString()
- + ": " + e.toString(), e);
- }
+ if (info != null) {
+ try {
+ // First create a thumbnail for the activity...
+ // For now, don't create the thumbnail here; we are
+ // doing that by doing a screen snapshot.
+ info.setDescription(r.activity.onCreateDescription());
+ } catch (Exception e) {
+ if (!mInstrumentation.onException(r.activity, e)) {
+ throw new RuntimeException(
+ "Unable to save state of activity "
+ + r.intent.getComponent().toShortString()
+ + ": " + e.toString(), e);
}
}
@@ -4927,9 +4903,8 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleStopActivity(IBinder token, int configChanges,
+ public void handleStopActivity(ActivityClientRecord r, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
- final ActivityClientRecord r = mActivities.get(token);
r.activity.mConfigChangeFlags |= configChanges;
final StopInfo stopInfo = new StopInfo();
@@ -4965,8 +4940,7 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void performRestartActivity(IBinder token, boolean start) {
- ActivityClientRecord r = mActivities.get(token);
+ public void performRestartActivity(ActivityClientRecord r, boolean start) {
if (r.stopped) {
r.activity.performRestart(start, "performRestartActivity");
if (start) {
@@ -5053,107 +5027,101 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleSendResult(IBinder token, List<ResultInfo> results, String reason) {
- ActivityClientRecord r = mActivities.get(token);
+ public void handleSendResult(ActivityClientRecord r, List<ResultInfo> results, String reason) {
if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
- if (r != null) {
- final boolean resumed = !r.paused;
- if (!r.activity.mFinished && r.activity.mDecor != null
- && r.hideForNow && resumed) {
- // We had hidden the activity because it started another
- // one... we have gotten a result back and we are not
- // paused, so make sure our window is visible.
- updateVisibility(r, true);
- }
- if (resumed) {
- try {
- // Now we are idle.
- r.activity.mCalled = false;
- mInstrumentation.callActivityOnPause(r.activity);
- if (!r.activity.mCalled) {
- throw new SuperNotCalledException(
- "Activity " + r.intent.getComponent().toShortString()
- + " did not call through to super.onPause()");
- }
- } catch (SuperNotCalledException e) {
- throw e;
- } catch (Exception e) {
- if (!mInstrumentation.onException(r.activity, e)) {
- throw new RuntimeException(
- "Unable to pause activity "
- + r.intent.getComponent().toShortString()
- + ": " + e.toString(), e);
- }
+ final boolean resumed = !r.paused;
+ if (!r.activity.mFinished && r.activity.mDecor != null
+ && r.hideForNow && resumed) {
+ // We had hidden the activity because it started another
+ // one... we have gotten a result back and we are not
+ // paused, so make sure our window is visible.
+ updateVisibility(r, true);
+ }
+ if (resumed) {
+ try {
+ // Now we are idle.
+ r.activity.mCalled = false;
+ mInstrumentation.callActivityOnPause(r.activity);
+ if (!r.activity.mCalled) {
+ throw new SuperNotCalledException(
+ "Activity " + r.intent.getComponent().toShortString()
+ + " did not call through to super.onPause()");
+ }
+ } catch (SuperNotCalledException e) {
+ throw e;
+ } catch (Exception e) {
+ if (!mInstrumentation.onException(r.activity, e)) {
+ throw new RuntimeException(
+ "Unable to pause activity "
+ + r.intent.getComponent().toShortString()
+ + ": " + e.toString(), e);
}
- }
- checkAndBlockForNetworkAccess();
- deliverResults(r, results, reason);
- if (resumed) {
- r.activity.performResume(false, reason);
}
}
+ checkAndBlockForNetworkAccess();
+ deliverResults(r, results, reason);
+ if (resumed) {
+ r.activity.performResume(false, reason);
+ }
}
/** Core implementation of activity destroy call. */
- ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
+ ActivityClientRecord performDestroyActivity(ActivityClientRecord r, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
- ActivityClientRecord r = mActivities.get(token);
Class<? extends Activity> activityClass = null;
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
- if (r != null) {
- activityClass = r.activity.getClass();
- r.activity.mConfigChangeFlags |= configChanges;
- if (finishing) {
- r.activity.mFinished = true;
- }
+ activityClass = r.activity.getClass();
+ r.activity.mConfigChangeFlags |= configChanges;
+ if (finishing) {
+ r.activity.mFinished = true;
+ }
- performPauseActivityIfNeeded(r, "destroy");
+ performPauseActivityIfNeeded(r, "destroy");
- if (!r.stopped) {
- callActivityOnStop(r, false /* saveState */, "destroy");
- }
- if (getNonConfigInstance) {
- try {
- r.lastNonConfigurationInstances
- = r.activity.retainNonConfigurationInstances();
- } catch (Exception e) {
- if (!mInstrumentation.onException(r.activity, e)) {
- throw new RuntimeException(
- "Unable to retain activity "
- + r.intent.getComponent().toShortString()
- + ": " + e.toString(), e);
- }
- }
- }
+ if (!r.stopped) {
+ callActivityOnStop(r, false /* saveState */, "destroy");
+ }
+ if (getNonConfigInstance) {
try {
- r.activity.mCalled = false;
- mInstrumentation.callActivityOnDestroy(r.activity);
- if (!r.activity.mCalled) {
- throw new SuperNotCalledException(
- "Activity " + safeToComponentShortString(r.intent) +
- " did not call through to super.onDestroy()");
- }
- if (r.window != null) {
- r.window.closeAllPanels();
- }
- } catch (SuperNotCalledException e) {
- throw e;
+ r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
- "Unable to destroy activity " + safeToComponentShortString(r.intent)
+ "Unable to retain activity "
+ + r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
r.setState(ON_DESTROY);
mLastReportedWindowingMode.remove(r.activity.getActivityToken());
}
+ try {
+ r.activity.mCalled = false;
+ mInstrumentation.callActivityOnDestroy(r.activity);
+ if (!r.activity.mCalled) {
+ throw new SuperNotCalledException(
+ "Activity " + safeToComponentShortString(r.intent)
+ + " did not call through to super.onDestroy()");
+ }
+ if (r.window != null) {
+ r.window.closeAllPanels();
+ }
+ } catch (SuperNotCalledException e) {
+ throw e;
+ } catch (Exception e) {
+ if (!mInstrumentation.onException(r.activity, e)) {
+ throw new RuntimeException(
+ "Unable to destroy activity " + safeToComponentShortString(r.intent)
+ + ": " + e.toString(), e);
+ }
+ }
+ r.setState(ON_DESTROY);
schedulePurgeIdler();
// updatePendingActivityConfiguration() reads from mActivities to update
// ActivityClientRecord which runs in a different thread. Protect modifications to
// mActivities to avoid race.
synchronized (mResourcesManager) {
- mActivities.remove(token);
+ mActivities.remove(r.token);
}
StrictMode.decrementExpectedActivityCount(activityClass);
return r;
@@ -5170,70 +5138,67 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
+ public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
boolean getNonConfigInstance, String reason) {
- ActivityClientRecord r = performDestroyActivity(token, finishing,
- configChanges, getNonConfigInstance, reason);
- if (r != null) {
- cleanUpPendingRemoveWindows(r, finishing);
- WindowManager wm = r.activity.getWindowManager();
- View v = r.activity.mDecor;
- if (v != null) {
- if (r.activity.mVisibleFromServer) {
- mNumVisibleActivities--;
- }
- IBinder wtoken = v.getWindowToken();
- if (r.activity.mWindowAdded) {
- if (r.mPreserveWindow) {
- // Hold off on removing this until the new activity's
- // window is being added.
- r.mPendingRemoveWindow = r.window;
- r.mPendingRemoveWindowManager = wm;
- // We can only keep the part of the view hierarchy that we control,
- // everything else must be removed, because it might not be able to
- // behave properly when activity is relaunching.
- r.window.clearContentView();
- } else {
- wm.removeViewImmediate(v);
- }
- }
- if (wtoken != null && r.mPendingRemoveWindow == null) {
- WindowManagerGlobal.getInstance().closeAll(wtoken,
- r.activity.getClass().getName(), "Activity");
- } else if (r.mPendingRemoveWindow != null) {
- // We're preserving only one window, others should be closed so app views
- // will be detached before the final tear down. It should be done now because
- // some components (e.g. WebView) rely on detach callbacks to perform receiver
- // unregister and other cleanup.
- WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
- r.activity.getClass().getName(), "Activity");
+ r = performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);
+ cleanUpPendingRemoveWindows(r, finishing);
+ WindowManager wm = r.activity.getWindowManager();
+ View v = r.activity.mDecor;
+ if (v != null) {
+ if (r.activity.mVisibleFromServer) {
+ mNumVisibleActivities--;
+ }
+ IBinder wtoken = v.getWindowToken();
+ if (r.activity.mWindowAdded) {
+ if (r.mPreserveWindow) {
+ // Hold off on removing this until the new activity's
+ // window is being added.
+ r.mPendingRemoveWindow = r.window;
+ r.mPendingRemoveWindowManager = wm;
+ // We can only keep the part of the view hierarchy that we control,
+ // everything else must be removed, because it might not be able to
+ // behave properly when activity is relaunching.
+ r.window.clearContentView();
+ } else {
+ wm.removeViewImmediate(v);
}
- r.activity.mDecor = null;
- }
- if (r.mPendingRemoveWindow == null) {
- // If we are delaying the removal of the activity window, then
- // we can't clean up all windows here. Note that we can't do
- // so later either, which means any windows that aren't closed
- // by the app will leak. Well we try to warning them a lot
- // about leaking windows, because that is a bug, so if they are
- // using this recreate facility then they get to live with leaks.
- WindowManagerGlobal.getInstance().closeAll(token,
- r.activity.getClass().getName(), "Activity");
}
-
- // Mocked out contexts won't be participating in the normal
- // process lifecycle, but if we're running with a proper
- // ApplicationContext we need to have it tear down things
- // cleanly.
- Context c = r.activity.getBaseContext();
- if (c instanceof ContextImpl) {
- ((ContextImpl) c).scheduleFinalCleanup(
+ if (wtoken != null && r.mPendingRemoveWindow == null) {
+ WindowManagerGlobal.getInstance().closeAll(wtoken,
+ r.activity.getClass().getName(), "Activity");
+ } else if (r.mPendingRemoveWindow != null) {
+ // We're preserving only one window, others should be closed so app views
+ // will be detached before the final tear down. It should be done now because
+ // some components (e.g. WebView) rely on detach callbacks to perform receiver
+ // unregister and other cleanup.
+ WindowManagerGlobal.getInstance().closeAllExceptView(r.token, v,
r.activity.getClass().getName(), "Activity");
}
+ r.activity.mDecor = null;
+ }
+ if (r.mPendingRemoveWindow == null) {
+ // If we are delaying the removal of the activity window, then
+ // we can't clean up all windows here. Note that we can't do
+ // so later either, which means any windows that aren't closed
+ // by the app will leak. Well we try to warning them a lot
+ // about leaking windows, because that is a bug, so if they are
+ // using this recreate facility then they get to live with leaks.
+ WindowManagerGlobal.getInstance().closeAll(r.token,
+ r.activity.getClass().getName(), "Activity");
+ }
+
+ // Mocked out contexts won't be participating in the normal
+ // process lifecycle, but if we're running with a proper
+ // ApplicationContext we need to have it tear down things
+ // cleanly.
+ Context c = r.activity.getBaseContext();
+ if (c instanceof ContextImpl) {
+ ((ContextImpl) c).scheduleFinalCleanup(
+ r.activity.getClass().getName(), "Activity");
}
if (finishing) {
try {
- ActivityTaskManager.getService().activityDestroyed(token);
+ ActivityTaskManager.getService().activityDestroyed(r.token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -5456,7 +5421,7 @@ public final class ActivityThread extends ClientTransactionHandler {
callActivityOnStop(r, true /* saveState */, reason);
}
- handleDestroyActivity(r.token, false, configChanges, true, reason);
+ handleDestroyActivity(r, false, configChanges, true, reason);
r.activity = null;
r.window = null;
@@ -5484,12 +5449,10 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void reportRelaunch(IBinder token, PendingTransactionActions pendingActions) {
+ public void reportRelaunch(ActivityClientRecord r, PendingTransactionActions pendingActions) {
try {
- ActivityTaskManager.getService().activityRelaunched(token);
- final ActivityClientRecord r = mActivities.get(token);
- if (pendingActions.shouldReportRelaunchToWindowManager() && r != null
- && r.window != null) {
+ ActivityTaskManager.getService().activityRelaunched(r.token);
+ if (pendingActions.shouldReportRelaunchToWindowManager() && r.window != null) {
r.window.reportActivityRelaunched();
}
} catch (RemoteException e) {
@@ -5648,13 +5611,7 @@ public final class ActivityThread extends ClientTransactionHandler {
*/
private Configuration performActivityConfigurationChanged(Activity activity,
Configuration newConfig, Configuration amOverrideConfig, int displayId) {
- if (activity == null) {
- throw new IllegalArgumentException("No activity provided.");
- }
final IBinder activityToken = activity.getActivityToken();
- if (activityToken == null) {
- throw new IllegalArgumentException("Activity token not set. Is the activity attached?");
- }
final boolean movedToDifferentDisplay = isDifferentDisplay(activity, displayId);
boolean shouldReportChange = false;
@@ -5954,20 +5911,8 @@ public final class ActivityThread extends ClientTransactionHandler {
* processing any configurations older than {@code overrideConfig}.
*/
@Override
- public void updatePendingActivityConfiguration(IBinder activityToken,
+ public void updatePendingActivityConfiguration(ActivityClientRecord r,
Configuration overrideConfig) {
- final ActivityClientRecord r;
- synchronized (mResourcesManager) {
- r = mActivities.get(activityToken);
- }
-
- if (r == null) {
- if (DEBUG_CONFIGURATION) {
- Slog.w(TAG, "Not found target activity to update its pending config.");
- }
- return;
- }
-
synchronized (r) {
if (r.mPendingOverrideConfig != null
&& !r.mPendingOverrideConfig.isOtherSeqNewer(overrideConfig)) {
@@ -5987,21 +5932,14 @@ public final class ActivityThread extends ClientTransactionHandler {
* if {@link #updatePendingActivityConfiguration(IBinder, Configuration)} has been called with
* a newer config than {@code overrideConfig}.
*
- * @param activityToken Target activity token.
+ * @param r Target activity record.
* @param overrideConfig Activity override config.
* @param displayId Id of the display where activity was moved to, -1 if there was no move and
* value didn't change.
*/
@Override
- public void handleActivityConfigurationChanged(IBinder activityToken,
+ public void handleActivityConfigurationChanged(ActivityClientRecord r,
@NonNull Configuration overrideConfig, int displayId) {
- ActivityClientRecord r = mActivities.get(activityToken);
- // Check input params.
- if (r == null || r.activity == null) {
- if (DEBUG_CONFIGURATION) Slog.w(TAG, "Not found target activity to report to: " + r);
- return;
- }
-
synchronized (r) {
if (overrideConfig.isOtherSeqNewer(r.mPendingOverrideConfig)) {
if (DEBUG_CONFIGURATION) {
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index 15237beee805..08cd0b34ee0a 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -243,8 +243,8 @@ public class ApplicationLoaders {
// cached must be built and loaded in the same environment
if (!sharedLibrariesEquals(sharedLibraries, cached.sharedLibraries)) {
- Log.w(TAG, "Unexpected environment for cached library: (" + sharedLibraries + "|"
- + cached.sharedLibraries + ")");
+ Log.w(TAG, "Unexpected environment loading cached library " + zip + " (real|cached): ("
+ + sharedLibraries + "|" + cached.sharedLibraries + ")");
return null;
}
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index dedd8705ef55..676c6c01d349 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -684,8 +684,7 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public int checkPermission(String permName, String pkgName) {
- return PermissionManager
- .checkPackageNamePermission(permName, pkgName, getUserId());
+ return PermissionManager.checkPackageNamePermission(permName, pkgName, getUserId());
}
@Override
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index 2df756e80fde..ac50676ff46b 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -15,6 +15,8 @@
*/
package android.app;
+import android.annotation.NonNull;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.ClientTransactionItem;
import android.app.servertransaction.PendingTransactionActions;
@@ -89,37 +91,38 @@ public abstract class ClientTransactionHandler {
public abstract Map<IBinder, ClientTransactionItem> getActivitiesToBeDestroyed();
/** Destroy the activity. */
- public abstract void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
- boolean getNonConfigInstance, String reason);
+ public abstract void handleDestroyActivity(@NonNull ActivityClientRecord r, boolean finishing,
+ int configChanges, boolean getNonConfigInstance, String reason);
/** Pause the activity. */
- public abstract void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
- int configChanges, PendingTransactionActions pendingActions, String reason);
+ public abstract void handlePauseActivity(@NonNull ActivityClientRecord r, boolean finished,
+ boolean userLeaving, int configChanges, PendingTransactionActions pendingActions,
+ String reason);
/**
* Resume the activity.
- * @param token Target activity token.
+ * @param r Target activity record.
* @param finalStateRequest Flag indicating if this call is handling final lifecycle state
* request for a transaction.
* @param isForward Flag indicating if next transition is forward.
* @param reason Reason for performing this operation.
*/
- public abstract void handleResumeActivity(IBinder token, boolean finalStateRequest,
- boolean isForward, String reason);
+ public abstract void handleResumeActivity(@NonNull ActivityClientRecord r,
+ boolean finalStateRequest, boolean isForward, String reason);
/**
* Notify the activity about top resumed state change.
- * @param token Target activity token.
+ * @param r Target activity record.
* @param isTopResumedActivity Current state of the activity, {@code true} if it's the
* topmost resumed activity in the system, {@code false} otherwise.
* @param reason Reason for performing this operation.
*/
- public abstract void handleTopResumedActivityChanged(IBinder token,
+ public abstract void handleTopResumedActivityChanged(@NonNull ActivityClientRecord r,
boolean isTopResumedActivity, String reason);
/**
* Stop the activity.
- * @param token Target activity token.
+ * @param r Target activity record.
* @param configChanges Activity configuration changes.
* @param pendingActions Pending actions to be used on this or later stages of activity
* transaction.
@@ -127,38 +130,40 @@ public abstract class ClientTransactionHandler {
* request for a transaction.
* @param reason Reason for performing this operation.
*/
- public abstract void handleStopActivity(IBinder token, int configChanges,
+ public abstract void handleStopActivity(@NonNull ActivityClientRecord r, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason);
/** Report that activity was stopped to server. */
public abstract void reportStop(PendingTransactionActions pendingActions);
/** Restart the activity after it was stopped. */
- public abstract void performRestartActivity(IBinder token, boolean start);
+ public abstract void performRestartActivity(@NonNull ActivityClientRecord r, boolean start);
/** Set pending activity configuration in case it will be updated by other transaction item. */
- public abstract void updatePendingActivityConfiguration(IBinder activityToken,
+ public abstract void updatePendingActivityConfiguration(@NonNull ActivityClientRecord r,
Configuration overrideConfig);
/** Deliver activity (override) configuration change. */
- public abstract void handleActivityConfigurationChanged(IBinder activityToken,
+ public abstract void handleActivityConfigurationChanged(@NonNull ActivityClientRecord r,
Configuration overrideConfig, int displayId);
/** Deliver result from another activity. */
- public abstract void handleSendResult(IBinder token, List<ResultInfo> results, String reason);
+ public abstract void handleSendResult(
+ @NonNull ActivityClientRecord r, List<ResultInfo> results, String reason);
/** Deliver new intent. */
- public abstract void handleNewIntent(IBinder token, List<ReferrerIntent> intents);
+ public abstract void handleNewIntent(
+ @NonNull ActivityClientRecord r, List<ReferrerIntent> intents);
/** Request that an activity enter picture-in-picture. */
- public abstract void handlePictureInPictureRequested(IBinder token);
+ public abstract void handlePictureInPictureRequested(@NonNull ActivityClientRecord r);
/** Perform activity launch. */
- public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
+ public abstract Activity handleLaunchActivity(@NonNull ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent);
/** Perform activity start. */
- public abstract void handleStartActivity(IBinder token,
+ public abstract void handleStartActivity(@NonNull ActivityClientRecord r,
PendingTransactionActions pendingActions);
/** Get package info. */
@@ -176,7 +181,7 @@ public abstract class ClientTransactionHandler {
* Get {@link android.app.ActivityThread.ActivityClientRecord} instance that corresponds to the
* provided token.
*/
- public abstract ActivityThread.ActivityClientRecord getActivityClient(IBinder token);
+ public abstract ActivityClientRecord getActivityClient(IBinder token);
/**
* Prepare activity relaunch to update internal bookkeeping. This is used to track multiple
@@ -191,7 +196,7 @@ public abstract class ClientTransactionHandler {
* @return An initialized instance of {@link ActivityThread.ActivityClientRecord} to use during
* relaunch, or {@code null} if relaunch cancelled.
*/
- public abstract ActivityThread.ActivityClientRecord prepareRelaunchActivity(IBinder token,
+ public abstract ActivityClientRecord prepareRelaunchActivity(IBinder token,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
int configChanges, MergedConfiguration config, boolean preserveWindow);
@@ -200,14 +205,15 @@ public abstract class ClientTransactionHandler {
* @param r Activity client record prepared for relaunch.
* @param pendingActions Pending actions to be used on later stages of activity transaction.
* */
- public abstract void handleRelaunchActivity(ActivityThread.ActivityClientRecord r,
+ public abstract void handleRelaunchActivity(@NonNull ActivityClientRecord r,
PendingTransactionActions pendingActions);
/**
* Report that relaunch request was handled.
- * @param token Target activity token.
+ * @param r Target activity record.
* @param pendingActions Pending actions initialized on earlier stages of activity transaction.
* Used to check if we should report relaunch to WM.
* */
- public abstract void reportRelaunch(IBinder token, PendingTransactionActions pendingActions);
+ public abstract void reportRelaunch(@NonNull ActivityClientRecord r,
+ PendingTransactionActions pendingActions);
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 93dfc79109a6..f37ca61ba69f 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -461,7 +461,7 @@ interface IActivityManager {
@UnsupportedAppUsage
Rect getTaskBounds(int taskId);
@UnsupportedAppUsage
- boolean setProcessMemoryTrimLevel(in String process, int uid, int level);
+ boolean setProcessMemoryTrimLevel(in String process, int userId, int level);
// Start of L transactions
diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java
index 7cdf85e0a6b8..d61c5d5ccd3d 100644
--- a/core/java/android/app/LocalActivityManager.java
+++ b/core/java/android/app/LocalActivityManager.java
@@ -49,6 +49,7 @@ public class LocalActivityManager {
private static final String TAG = "LocalActivityManager";
private static final boolean localLOGV = false;
+ // TODO(b/127877792): try to remove this and use {@code ActivityClientRecord} instead.
// Internal token for an Activity being managed by LocalActivityManager.
private static class LocalActivityRecord extends Binder {
LocalActivityRecord(String _id, Intent _intent) {
@@ -136,7 +137,7 @@ public class LocalActivityManager {
// startActivity() has not yet been called, so nothing to do.
return;
}
-
+
if (r.curState == INITIALIZING) {
// Get the lastNonConfigurationInstance for the activity
HashMap<String, Object> lastNonConfigurationInstances =
@@ -177,12 +178,13 @@ public class LocalActivityManager {
pendingActions = null;
}
- mActivityThread.handleStartActivity(r, pendingActions);
+ mActivityThread.handleStartActivity(clientRecord, pendingActions);
r.curState = STARTED;
if (desiredState == RESUMED) {
if (localLOGV) Log.v(TAG, r.id + ": resuming");
- mActivityThread.performResumeActivity(r, true, "moveToState-INITIALIZING");
+ mActivityThread.performResumeActivity(clientRecord, true,
+ "moveToState-INITIALIZING");
r.curState = RESUMED;
}
@@ -194,18 +196,21 @@ public class LocalActivityManager {
// group's state catches up.
return;
}
-
+
+ final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
+
switch (r.curState) {
case CREATED:
if (desiredState == STARTED) {
if (localLOGV) Log.v(TAG, r.id + ": restarting");
- mActivityThread.performRestartActivity(r, true /* start */);
+ mActivityThread.performRestartActivity(clientRecord, true /* start */);
r.curState = STARTED;
}
if (desiredState == RESUMED) {
if (localLOGV) Log.v(TAG, r.id + ": restarting and resuming");
- mActivityThread.performRestartActivity(r, true /* start */);
- mActivityThread.performResumeActivity(r, true, "moveToState-CREATED");
+ mActivityThread.performRestartActivity(clientRecord, true /* start */);
+ mActivityThread.performResumeActivity(clientRecord, true,
+ "moveToState-CREATED");
r.curState = RESUMED;
}
return;
@@ -214,7 +219,8 @@ public class LocalActivityManager {
if (desiredState == RESUMED) {
// Need to resume it...
if (localLOGV) Log.v(TAG, r.id + ": resuming");
- mActivityThread.performResumeActivity(r, true, "moveToState-STARTED");
+ mActivityThread.performResumeActivity(clientRecord, true,
+ "moveToState-STARTED");
r.instanceState = null;
r.curState = RESUMED;
}
@@ -352,7 +358,8 @@ public class LocalActivityManager {
ArrayList<ReferrerIntent> intents = new ArrayList<>(1);
intents.add(new ReferrerIntent(intent, mParent.getPackageName()));
if (localLOGV) Log.v(TAG, r.id + ": new intent");
- mActivityThread.handleNewIntent(r, intents);
+ final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
+ mActivityThread.handleNewIntent(clientRecord, intents);
r.intent = intent;
moveToState(r, mCurState);
if (mSingleMode) {
@@ -399,7 +406,8 @@ public class LocalActivityManager {
performPause(r, finish);
}
if (localLOGV) Log.v(TAG, r.id + ": destroying");
- mActivityThread.performDestroyActivity(r, finish, 0 /* configChanges */,
+ final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
+ mActivityThread.performDestroyActivity(clientRecord, finish, 0 /* configChanges */,
false /* getNonConfigInstance */, "LocalActivityManager::performDestroy");
r.activity = null;
r.window = null;
@@ -664,7 +672,8 @@ public class LocalActivityManager {
for (int i=0; i<N; i++) {
LocalActivityRecord r = mActivityArray.get(i);
if (localLOGV) Log.v(TAG, r.id + ": destroying");
- mActivityThread.performDestroyActivity(r, finishing, 0 /* configChanges */,
+ final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
+ mActivityThread.performDestroyActivity(clientRecord, finishing, 0 /* configChanges */,
false /* getNonConfigInstance */, "LocalActivityManager::dispatchDestroy");
}
mActivities.clear();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 6f3e89229e4c..6737972dc34e 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5187,19 +5187,11 @@ public class Notification implements Parcelable
bindHeaderChronometerAndTime(contentView, p);
bindProfileBadge(contentView, p);
bindAlertedIcon(contentView, p);
- bindActivePermissions(contentView, p);
bindFeedbackIcon(contentView, p);
bindExpandButton(contentView, p);
mN.mUsesStandardHeader = true;
}
- private void bindActivePermissions(RemoteViews contentView, StandardTemplateParams p) {
- int color = getNeutralColor(p);
- contentView.setDrawableTint(R.id.camera, false, color, PorterDuff.Mode.SRC_ATOP);
- contentView.setDrawableTint(R.id.mic, false, color, PorterDuff.Mode.SRC_ATOP);
- contentView.setDrawableTint(R.id.overlay, false, color, PorterDuff.Mode.SRC_ATOP);
- }
-
private void bindFeedbackIcon(RemoteViews contentView, StandardTemplateParams p) {
int color = getNeutralColor(p);
contentView.setDrawableTint(R.id.feedback, false, color, PorterDuff.Mode.SRC_ATOP);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 8ee995d6e6be..0627bc855934 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -282,6 +282,16 @@ public class NotificationManager {
= "android.app.action.INTERRUPTION_FILTER_CHANGED";
/**
+ * Intent that is broadcast when the state of
+ * {@link #hasEnabledNotificationListener(String, UserHandle)} changes.
+ * @hide
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public static final String ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED =
+ "android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED";
+
+ /**
* Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
* @hide
*/
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index fe509dea2def..4139b2faeb1b 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -65,6 +65,33 @@
{
"name": "CtsInstantAppTests",
"file_patterns": ["(/|^)InstantAppResolve[^/]*"]
+ },
+ {
+ "name": "CtsAutoFillServiceTestCases",
+ "options": [
+ {
+ "include-filter": "android.autofillservice.cts.PreSimpleSaveActivityTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ],
+ "file_patterns": ["(/|^)Activity.java"]
+ },
+ {
+ "name": "CtsAutoFillServiceTestCases",
+ "options": [
+ {
+ "include-filter": "android.autofillservice.cts.SimpleSaveActivityTest"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.AppModeFull"
+ }
+ ],
+ "file_patterns": ["(/|^)Activity.java"]
}
],
"postsubmit": [
diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
index 8b52242a6b6c..8a4bee98ca87 100644
--- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
@@ -20,6 +20,7 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.INVALID_DISPLAY;
import android.annotation.NonNull;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.content.res.Configuration;
import android.os.IBinder;
@@ -32,23 +33,24 @@ import java.util.Objects;
* Activity configuration changed callback.
* @hide
*/
-public class ActivityConfigurationChangeItem extends ClientTransactionItem {
+public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
private Configuration mConfiguration;
@Override
public void preExecute(android.app.ClientTransactionHandler client, IBinder token) {
+ final ActivityClientRecord r = getActivityClientRecord(client, token);
// Notify the client of an upcoming change in the token configuration. This ensures that
// batches of config change items only process the newest configuration.
- client.updatePendingActivityConfiguration(token, mConfiguration);
+ client.updatePendingActivityConfiguration(r, mConfiguration);
}
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
// TODO(lifecycler): detect if PIP or multi-window mode changed and report it here.
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
- client.handleActivityConfigurationChanged(token, mConfiguration, INVALID_DISPLAY);
+ client.handleActivityConfigurationChanged(r, mConfiguration, INVALID_DISPLAY);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -93,7 +95,7 @@ public class ActivityConfigurationChangeItem extends ClientTransactionItem {
mConfiguration = in.readTypedObject(Configuration.CREATOR);
}
- public static final @android.annotation.NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
+ public static final @NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
new Creator<ActivityConfigurationChangeItem>() {
public ActivityConfigurationChangeItem createFromParcel(Parcel in) {
return new ActivityConfigurationChangeItem(in);
diff --git a/core/java/android/app/servertransaction/ActivityLifecycleItem.java b/core/java/android/app/servertransaction/ActivityLifecycleItem.java
index c9193a9578e7..cadb6606b1be 100644
--- a/core/java/android/app/servertransaction/ActivityLifecycleItem.java
+++ b/core/java/android/app/servertransaction/ActivityLifecycleItem.java
@@ -25,7 +25,7 @@ import java.lang.annotation.RetentionPolicy;
* Request for lifecycle state that an activity should reach.
* @hide
*/
-public abstract class ActivityLifecycleItem extends ClientTransactionItem {
+public abstract class ActivityLifecycleItem extends ActivityTransactionItem {
@IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = {
UNDEFINED,
diff --git a/core/java/android/app/servertransaction/ActivityRelaunchItem.java b/core/java/android/app/servertransaction/ActivityRelaunchItem.java
index 9844de7b6e88..87ea3f8db39c 100644
--- a/core/java/android/app/servertransaction/ActivityRelaunchItem.java
+++ b/core/java/android/app/servertransaction/ActivityRelaunchItem.java
@@ -18,7 +18,8 @@ package android.app.servertransaction;
import static android.app.ActivityThread.DEBUG_ORDER;
-import android.app.ActivityThread;
+import android.annotation.NonNull;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.app.ResultInfo;
import android.os.IBinder;
@@ -36,7 +37,7 @@ import java.util.Objects;
* Activity relaunch callback.
* @hide
*/
-public class ActivityRelaunchItem extends ClientTransactionItem {
+public class ActivityRelaunchItem extends ActivityTransactionItem {
private static final String TAG = "ActivityRelaunchItem";
@@ -50,7 +51,7 @@ public class ActivityRelaunchItem extends ClientTransactionItem {
* A record that was properly configured for relaunch. Execution will be cancelled if not
* initialized after {@link #preExecute(ClientTransactionHandler, IBinder)}.
*/
- private ActivityThread.ActivityClientRecord mActivityClientRecord;
+ private ActivityClientRecord mActivityClientRecord;
@Override
public void preExecute(ClientTransactionHandler client, IBinder token) {
@@ -59,7 +60,7 @@ public class ActivityRelaunchItem extends ClientTransactionItem {
}
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
if (mActivityClientRecord == null) {
if (DEBUG_ORDER) Slog.d(TAG, "Activity relaunch cancelled");
@@ -73,7 +74,8 @@ public class ActivityRelaunchItem extends ClientTransactionItem {
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
- client.reportRelaunch(token, pendingActions);
+ final ActivityClientRecord r = getActivityClientRecord(client, token);
+ client.reportRelaunch(r, pendingActions);
}
// ObjectPoolItem implementation
@@ -130,16 +132,16 @@ public class ActivityRelaunchItem extends ClientTransactionItem {
mPreserveWindow = in.readBoolean();
}
- public static final @android.annotation.NonNull Creator<ActivityRelaunchItem> CREATOR =
+ public static final @NonNull Creator<ActivityRelaunchItem> CREATOR =
new Creator<ActivityRelaunchItem>() {
- public ActivityRelaunchItem createFromParcel(Parcel in) {
- return new ActivityRelaunchItem(in);
- }
-
- public ActivityRelaunchItem[] newArray(int size) {
- return new ActivityRelaunchItem[size];
- }
- };
+ public ActivityRelaunchItem createFromParcel(Parcel in) {
+ return new ActivityRelaunchItem(in);
+ }
+
+ public ActivityRelaunchItem[] newArray(int size) {
+ return new ActivityRelaunchItem[size];
+ }
+ };
@Override
public boolean equals(Object o) {
diff --git a/core/java/android/app/servertransaction/ActivityResultItem.java b/core/java/android/app/servertransaction/ActivityResultItem.java
index 4e743caccad6..47096a8257e9 100644
--- a/core/java/android/app/servertransaction/ActivityResultItem.java
+++ b/core/java/android/app/servertransaction/ActivityResultItem.java
@@ -18,10 +18,11 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import android.annotation.NonNull;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.app.ResultInfo;
import android.compat.annotation.UnsupportedAppUsage;
-import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Trace;
@@ -33,7 +34,7 @@ import java.util.Objects;
* Activity result delivery callback.
* @hide
*/
-public class ActivityResultItem extends ClientTransactionItem {
+public class ActivityResultItem extends ActivityTransactionItem {
@UnsupportedAppUsage
private List<ResultInfo> mResultInfoList;
@@ -45,10 +46,10 @@ public class ActivityResultItem extends ClientTransactionItem {
}*/
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
- client.handleSendResult(token, mResultInfoList, "ACTIVITY_RESULT");
+ client.handleSendResult(r, mResultInfoList, "ACTIVITY_RESULT");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -88,7 +89,7 @@ public class ActivityResultItem extends ClientTransactionItem {
mResultInfoList = in.createTypedArrayList(ResultInfo.CREATOR);
}
- public static final @android.annotation.NonNull Parcelable.Creator<ActivityResultItem> CREATOR =
+ public static final @NonNull Parcelable.Creator<ActivityResultItem> CREATOR =
new Parcelable.Creator<ActivityResultItem>() {
public ActivityResultItem createFromParcel(Parcel in) {
return new ActivityResultItem(in);
diff --git a/core/java/android/app/servertransaction/ActivityTransactionItem.java b/core/java/android/app/servertransaction/ActivityTransactionItem.java
new file mode 100644
index 000000000000..f7d7e9d20ab9
--- /dev/null
+++ b/core/java/android/app/servertransaction/ActivityTransactionItem.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.servertransaction;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
+import android.annotation.NonNull;
+import android.app.ActivityThread.ActivityClientRecord;
+import android.app.ClientTransactionHandler;
+import android.os.IBinder;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * An activity-targeting callback message to a client that can be scheduled and executed.
+ * It also provides nullity-free version of
+ * {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)} for child class
+ * to inherit.
+ *
+ * @see ClientTransaction
+ * @see ClientTransactionItem
+ * @see com.android.server.wm.ClientLifecycleManager
+ * @hide
+ */
+public abstract class ActivityTransactionItem extends ClientTransactionItem {
+ @Override
+ public final void execute(ClientTransactionHandler client, IBinder token,
+ PendingTransactionActions pendingActions) {
+ final ActivityClientRecord r = getActivityClientRecord(client, token);
+
+ execute(client, r, pendingActions);
+ }
+
+ /**
+ * Like {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)},
+ * but take non-null {@link ActivityClientRecord} as a parameter.
+ */
+ @VisibleForTesting(visibility = PACKAGE)
+ public abstract void execute(@NonNull ClientTransactionHandler client,
+ @NonNull ActivityClientRecord r, PendingTransactionActions pendingActions);
+
+ @NonNull ActivityClientRecord getActivityClientRecord(
+ @NonNull ClientTransactionHandler client, IBinder token) {
+ final ActivityClientRecord r = client.getActivityClient(token);
+ if (r == null) {
+ throw new IllegalArgumentException("Activity client record must not be null to execute "
+ + "transaction item");
+ }
+ if (client.getActivity(token) == null) {
+ throw new IllegalArgumentException("Activity must not be null to execute "
+ + "transaction item");
+ }
+ return r;
+ }
+}
diff --git a/core/java/android/app/servertransaction/DestroyActivityItem.java b/core/java/android/app/servertransaction/DestroyActivityItem.java
index 3ee761477efd..1611369497e9 100644
--- a/core/java/android/app/servertransaction/DestroyActivityItem.java
+++ b/core/java/android/app/servertransaction/DestroyActivityItem.java
@@ -18,6 +18,8 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import android.annotation.NonNull;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
import android.os.Parcel;
@@ -38,10 +40,10 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
}
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
- client.handleDestroyActivity(token, mFinished, mConfigChanges,
+ client.handleDestroyActivity(r, mFinished, mConfigChanges,
false /* getNonConfigInstance */, "DestroyActivityItem");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -92,7 +94,7 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
mConfigChanges = in.readInt();
}
- public static final @android.annotation.NonNull Creator<DestroyActivityItem> CREATOR =
+ public static final @NonNull Creator<DestroyActivityItem> CREATOR =
new Creator<DestroyActivityItem>() {
public DestroyActivityItem createFromParcel(Parcel in) {
return new DestroyActivityItem(in);
diff --git a/core/java/android/app/servertransaction/EnterPipRequestedItem.java b/core/java/android/app/servertransaction/EnterPipRequestedItem.java
index b2a1276fa178..b7e81a56afad 100644
--- a/core/java/android/app/servertransaction/EnterPipRequestedItem.java
+++ b/core/java/android/app/servertransaction/EnterPipRequestedItem.java
@@ -16,20 +16,20 @@
package android.app.servertransaction;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
-import android.os.IBinder;
import android.os.Parcel;
/**
* Request an activity to enter picture-in-picture mode.
* @hide
*/
-public final class EnterPipRequestedItem extends ClientTransactionItem {
+public final class EnterPipRequestedItem extends ActivityTransactionItem {
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
- client.handlePictureInPictureRequested(token);
+ client.handlePictureInPictureRequested(r);
}
// ObjectPoolItem implementation
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index 2e7b6262c785..77457af77340 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -18,6 +18,7 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import android.annotation.NonNull;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.app.ProfilerInfo;
@@ -163,7 +164,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
in.readTypedObject(FixedRotationAdjustments.CREATOR));
}
- public static final @android.annotation.NonNull Creator<LaunchActivityItem> CREATOR =
+ public static final @NonNull Creator<LaunchActivityItem> CREATOR =
new Creator<LaunchActivityItem>() {
public LaunchActivityItem createFromParcel(Parcel in) {
return new LaunchActivityItem(in);
diff --git a/core/java/android/app/servertransaction/MoveToDisplayItem.java b/core/java/android/app/servertransaction/MoveToDisplayItem.java
index 9a457a3aad40..32de53f189b0 100644
--- a/core/java/android/app/servertransaction/MoveToDisplayItem.java
+++ b/core/java/android/app/servertransaction/MoveToDisplayItem.java
@@ -19,6 +19,7 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import android.annotation.NonNull;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.content.res.Configuration;
import android.os.IBinder;
@@ -31,23 +32,24 @@ import java.util.Objects;
* Activity move to a different display message.
* @hide
*/
-public class MoveToDisplayItem extends ClientTransactionItem {
+public class MoveToDisplayItem extends ActivityTransactionItem {
private int mTargetDisplayId;
private Configuration mConfiguration;
@Override
public void preExecute(ClientTransactionHandler client, IBinder token) {
+ final ActivityClientRecord r = getActivityClientRecord(client, token);
// Notify the client of an upcoming change in the token configuration. This ensures that
// batches of config change items only process the newest configuration.
- client.updatePendingActivityConfiguration(token, mConfiguration);
+ client.updatePendingActivityConfiguration(r, mConfiguration);
}
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityMovedToDisplay");
- client.handleActivityConfigurationChanged(token, mConfiguration, mTargetDisplayId);
+ client.handleActivityConfigurationChanged(r, mConfiguration, mTargetDisplayId);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -96,7 +98,8 @@ public class MoveToDisplayItem extends ClientTransactionItem {
mConfiguration = in.readTypedObject(Configuration.CREATOR);
}
- public static final @android.annotation.NonNull Creator<MoveToDisplayItem> CREATOR = new Creator<MoveToDisplayItem>() {
+ public static final @NonNull Creator<MoveToDisplayItem> CREATOR =
+ new Creator<MoveToDisplayItem>() {
public MoveToDisplayItem createFromParcel(Parcel in) {
return new MoveToDisplayItem(in);
}
diff --git a/core/java/android/app/servertransaction/NewIntentItem.java b/core/java/android/app/servertransaction/NewIntentItem.java
index 6a4996da38ca..b4e2a7bfa10f 100644
--- a/core/java/android/app/servertransaction/NewIntentItem.java
+++ b/core/java/android/app/servertransaction/NewIntentItem.java
@@ -19,9 +19,10 @@ package android.app.servertransaction;
import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
+import android.annotation.NonNull;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.compat.annotation.UnsupportedAppUsage;
-import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Trace;
@@ -35,7 +36,7 @@ import java.util.Objects;
* New intent message.
* @hide
*/
-public class NewIntentItem extends ClientTransactionItem {
+public class NewIntentItem extends ActivityTransactionItem {
@UnsupportedAppUsage
private List<ReferrerIntent> mIntents;
@@ -47,10 +48,10 @@ public class NewIntentItem extends ClientTransactionItem {
}
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
- client.handleNewIntent(token, mIntents);
+ client.handleNewIntent(r, mIntents);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -94,7 +95,7 @@ public class NewIntentItem extends ClientTransactionItem {
mIntents = in.createTypedArrayList(ReferrerIntent.CREATOR);
}
- public static final @android.annotation.NonNull Parcelable.Creator<NewIntentItem> CREATOR =
+ public static final @NonNull Parcelable.Creator<NewIntentItem> CREATOR =
new Parcelable.Creator<NewIntentItem>() {
public NewIntentItem createFromParcel(Parcel in) {
return new NewIntentItem(in);
diff --git a/core/java/android/app/servertransaction/PauseActivityItem.java b/core/java/android/app/servertransaction/PauseActivityItem.java
index f65c843ee76f..cb154e9585e6 100644
--- a/core/java/android/app/servertransaction/PauseActivityItem.java
+++ b/core/java/android/app/servertransaction/PauseActivityItem.java
@@ -18,8 +18,9 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import android.app.ActivityManager;
+import android.annotation.NonNull;
import android.app.ActivityTaskManager;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
import android.os.Parcel;
@@ -40,10 +41,10 @@ public class PauseActivityItem extends ActivityLifecycleItem {
private boolean mDontReport;
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
- client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
+ client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -130,7 +131,7 @@ public class PauseActivityItem extends ActivityLifecycleItem {
mDontReport = in.readBoolean();
}
- public static final @android.annotation.NonNull Creator<PauseActivityItem> CREATOR =
+ public static final @NonNull Creator<PauseActivityItem> CREATOR =
new Creator<PauseActivityItem>() {
public PauseActivityItem createFromParcel(Parcel in) {
return new PauseActivityItem(in);
diff --git a/core/java/android/app/servertransaction/ResumeActivityItem.java b/core/java/android/app/servertransaction/ResumeActivityItem.java
index 905076b08e69..d2a156c37c90 100644
--- a/core/java/android/app/servertransaction/ResumeActivityItem.java
+++ b/core/java/android/app/servertransaction/ResumeActivityItem.java
@@ -18,8 +18,10 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
import android.os.Parcel;
@@ -46,10 +48,10 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
}
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
- client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
+ client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -128,7 +130,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
mIsForward = in.readBoolean();
}
- public static final @android.annotation.NonNull Creator<ResumeActivityItem> CREATOR =
+ public static final @NonNull Creator<ResumeActivityItem> CREATOR =
new Creator<ResumeActivityItem>() {
public ResumeActivityItem createFromParcel(Parcel in) {
return new ResumeActivityItem(in);
diff --git a/core/java/android/app/servertransaction/StartActivityItem.java b/core/java/android/app/servertransaction/StartActivityItem.java
index 4fbe02b9cf76..ae0bd24218fb 100644
--- a/core/java/android/app/servertransaction/StartActivityItem.java
+++ b/core/java/android/app/servertransaction/StartActivityItem.java
@@ -18,8 +18,9 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import android.annotation.NonNull;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
-import android.os.IBinder;
import android.os.Parcel;
import android.os.Trace;
@@ -32,10 +33,10 @@ public class StartActivityItem extends ActivityLifecycleItem {
private static final String TAG = "StartActivityItem";
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "startActivityItem");
- client.handleStartActivity(token, pendingActions);
+ client.handleStartActivity(r, pendingActions);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -79,7 +80,7 @@ public class StartActivityItem extends ActivityLifecycleItem {
// Empty
}
- public static final @android.annotation.NonNull Creator<StartActivityItem> CREATOR =
+ public static final @NonNull Creator<StartActivityItem> CREATOR =
new Creator<StartActivityItem>() {
public StartActivityItem createFromParcel(Parcel in) {
return new StartActivityItem(in);
diff --git a/core/java/android/app/servertransaction/StopActivityItem.java b/core/java/android/app/servertransaction/StopActivityItem.java
index 8668bd49c8f5..7708104da16a 100644
--- a/core/java/android/app/servertransaction/StopActivityItem.java
+++ b/core/java/android/app/servertransaction/StopActivityItem.java
@@ -18,6 +18,8 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import android.annotation.NonNull;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
import android.os.Parcel;
@@ -34,10 +36,10 @@ public class StopActivityItem extends ActivityLifecycleItem {
private int mConfigChanges;
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
- client.handleStopActivity(token, mConfigChanges, pendingActions,
+ client.handleStopActivity(r, mConfigChanges, pendingActions,
true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -93,7 +95,7 @@ public class StopActivityItem extends ActivityLifecycleItem {
mConfigChanges = in.readInt();
}
- public static final @android.annotation.NonNull Creator<StopActivityItem> CREATOR =
+ public static final @NonNull Creator<StopActivityItem> CREATOR =
new Creator<StopActivityItem>() {
public StopActivityItem createFromParcel(Parcel in) {
return new StopActivityItem(in);
diff --git a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
index c7e4c3641631..345c1dd336ab 100644
--- a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
+++ b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
@@ -17,7 +17,9 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import android.annotation.NonNull;
import android.app.ActivityTaskManager;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
import android.os.Parcel;
@@ -28,15 +30,15 @@ import android.os.Trace;
* Top resumed activity changed callback.
* @hide
*/
-public class TopResumedActivityChangeItem extends ClientTransactionItem {
+public class TopResumedActivityChangeItem extends ActivityTransactionItem {
private boolean mOnTop;
@Override
- public void execute(ClientTransactionHandler client, IBinder token,
+ public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "topResumedActivityChangeItem");
- client.handleTopResumedActivityChanged(token, mOnTop, "topResumedActivityChangeItem");
+ client.handleTopResumedActivityChanged(r, mOnTop, "topResumedActivityChangeItem");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -97,16 +99,16 @@ public class TopResumedActivityChangeItem extends ClientTransactionItem {
mOnTop = in.readBoolean();
}
- public static final @android.annotation.NonNull Creator<TopResumedActivityChangeItem> CREATOR =
+ public static final @NonNull Creator<TopResumedActivityChangeItem> CREATOR =
new Creator<TopResumedActivityChangeItem>() {
- public TopResumedActivityChangeItem createFromParcel(Parcel in) {
- return new TopResumedActivityChangeItem(in);
- }
-
- public TopResumedActivityChangeItem[] newArray(int size) {
- return new TopResumedActivityChangeItem[size];
- }
- };
+ public TopResumedActivityChangeItem createFromParcel(Parcel in) {
+ return new TopResumedActivityChangeItem(in);
+ }
+
+ public TopResumedActivityChangeItem[] newArray(int size) {
+ return new TopResumedActivityChangeItem[size];
+ }
+ };
@Override
public boolean equals(Object o) {
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index 17fcda587322..3dcf2cb5f13e 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -218,29 +218,29 @@ public class TransactionExecutor {
null /* customIntent */);
break;
case ON_START:
- mTransactionHandler.handleStartActivity(r.token, mPendingActions);
+ mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
- mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
+ mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
- mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
+ mTransactionHandler.handlePauseActivity(r, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
- mTransactionHandler.handleStopActivity(r.token, 0 /* configChanges */,
+ mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
- mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
+ mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
- mTransactionHandler.performRestartActivity(r.token, false /* start */);
+ mTransactionHandler.performRestartActivity(r, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java
index bd1eea51f8af..cef6ab094177 100644
--- a/core/java/android/app/slice/SliceProvider.java
+++ b/core/java/android/app/slice/SliceProvider.java
@@ -155,10 +155,6 @@ public abstract class SliceProvider extends ContentProvider {
/**
* @hide
*/
- public static final String EXTRA_PROVIDER_PKG = "provider_pkg";
- /**
- * @hide
- */
public static final String EXTRA_RESULT = "result";
private static final boolean DEBUG = false;
@@ -519,7 +515,6 @@ public abstract class SliceProvider extends ContentProvider {
com.android.internal.R.string.config_slicePermissionComponent)));
intent.putExtra(EXTRA_BIND_URI, sliceUri);
intent.putExtra(EXTRA_PKG, callingPackage);
- intent.putExtra(EXTRA_PROVIDER_PKG, context.getPackageName());
// Unique pending intent.
intent.setData(sliceUri.buildUpon().appendQueryParameter("package", callingPackage)
.build());
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 19cb13c7e114..4f949cfc62a5 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -72,6 +72,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
private static final int MSG_SET_FEATURE_COMPLETED = 107;
private static final int MSG_CHALLENGE_GENERATED = 108;
private static final int MSG_FACE_DETECTED = 109;
+ private static final int MSG_CHALLENGE_INTERRUPTED = 110;
+ private static final int MSG_CHALLENGE_INTERRUPT_FINISHED = 111;
private final IFaceService mService;
private final Context mContext;
@@ -150,6 +152,16 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
mHandler.obtainMessage(MSG_CHALLENGE_GENERATED, challenge).sendToTarget();
}
}
+
+ @Override
+ public void onChallengeInterrupted(int sensorId) {
+ mHandler.obtainMessage(MSG_CHALLENGE_INTERRUPTED, sensorId).sendToTarget();
+ }
+
+ @Override
+ public void onChallengeInterruptFinished(int sensorId) {
+ mHandler.obtainMessage(MSG_CHALLENGE_INTERRUPT_FINISHED, sensorId).sendToTarget();
+ }
};
/**
@@ -1071,10 +1083,25 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
}
/**
+ * Callback structure provided to {@link #generateChallenge(GenerateChallengeCallback)}.
* @hide
*/
public interface GenerateChallengeCallback {
+ /**
+ * Invoked when a challenge has been generated.
+ */
void onGenerateChallengeResult(long challenge);
+
+ /**
+ * Invoked if the challenge has not been revoked and a subsequent caller/owner invokes
+ * {@link #generateChallenge(GenerateChallengeCallback)}, but
+ */
+ default void onChallengeInterrupted(int sensorId) {}
+
+ /**
+ * Invoked when the interrupting client has finished (e.g. revoked its challenge).
+ */
+ default void onChallengeInterruptFinished(int sensorId) {}
}
private abstract static class InternalGenerateChallengeCallback
@@ -1157,6 +1184,12 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
sendFaceDetected(msg.arg1 /* sensorId */, msg.arg2 /* userId */,
(boolean) msg.obj /* isStrongBiometric */);
break;
+ case MSG_CHALLENGE_INTERRUPTED:
+ sendChallengeInterrupted((int) msg.obj /* sensorId */);
+ break;
+ case MSG_CHALLENGE_INTERRUPT_FINISHED:
+ sendChallengeInterruptFinished((int) msg.obj /* sensorId */);
+ break;
default:
Slog.w(TAG, "Unknown message: " + msg.what);
}
@@ -1193,6 +1226,22 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
mFaceDetectionCallback.onFaceDetected(sensorId, userId, isStrongBiometric);
}
+ private void sendChallengeInterrupted(int sensorId) {
+ if (mGenerateChallengeCallback == null) {
+ Slog.e(TAG, "sendChallengeInterrupted, callback null");
+ return;
+ }
+ mGenerateChallengeCallback.onChallengeInterrupted(sensorId);
+ }
+
+ private void sendChallengeInterruptFinished(int sensorId) {
+ if (mGenerateChallengeCallback == null) {
+ Slog.e(TAG, "sendChallengeInterruptFinished, callback null");
+ return;
+ }
+ mGenerateChallengeCallback.onChallengeInterruptFinished(sensorId);
+ }
+
private void sendRemovedResult(Face face, int remaining) {
if (mRemovalCallback == null) {
return;
diff --git a/core/java/android/hardware/face/IFaceServiceReceiver.aidl b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
index 2600b7def03a..108f4f69bdd8 100644
--- a/core/java/android/hardware/face/IFaceServiceReceiver.aidl
+++ b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
@@ -32,4 +32,6 @@ oneway interface IFaceServiceReceiver {
void onFeatureSet(boolean success, int feature);
void onFeatureGet(boolean success, int feature, boolean value);
void onChallengeGenerated(long challenge);
+ void onChallengeInterrupted(int sensorId);
+ void onChallengeInterruptFinished(int sensorId);
}
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 7234eb1d81cd..cd26079a7bac 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -503,6 +503,10 @@ public class NetworkTemplate implements Parcelable {
for (final int ratType : ratTypes) {
collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(ratType));
}
+ // Add NETWORK_TYPE_5G_NSA to the returned list since 5G NSA is a virtual RAT type and
+ // it is not in TelephonyManager#NETWORK_TYPE_* constants.
+ // See {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}.
+ collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(NETWORK_TYPE_5G_NSA));
// Ensure that unknown type is returned.
collapsedRatTypes.add(TelephonyManager.NETWORK_TYPE_UNKNOWN);
return toIntArray(collapsedRatTypes);
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 1050c7f8b4f4..8e865e7ab313 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1012,10 +1012,16 @@ public class Build {
/**
* Q.
- * <p>
- * <em>Why? Why, to give you a taste of your future, a preview of things
- * to come. Con permiso, Capitan. The hall is rented, the orchestra
- * engaged. It's now time to see if you can dance.</em>
+ *
+ * <p>Applications targeting this or a later release will get these new changes in behavior.
+ * For more information about this release, see the
+ * <a href="/about/versions/10">Android 10 overview</a>.</p>
+ * <ul>
+ * <li><a href="/about/versions/10/behavior-changes-all">Behavior changes: all apps</a></li>
+ * <li><a href="/about/versions/10/behavior-changes-10">Behavior changes: apps targeting API
+ * 29+</a></li>
+ * </ul>
+ *
*/
public static final int Q = 29;
diff --git a/core/java/android/permission/PermissionControllerService.java b/core/java/android/permission/PermissionControllerService.java
index 8ad35e7eb37d..e2e61406ba95 100644
--- a/core/java/android/permission/PermissionControllerService.java
+++ b/core/java/android/permission/PermissionControllerService.java
@@ -35,6 +35,8 @@ import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.Service;
import android.app.admin.DevicePolicyManager.PermissionGrantState;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -83,6 +85,15 @@ public abstract class PermissionControllerService extends Service {
public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService";
/**
+ * A ChangeId indicating that this device supports camera and mic indicators. Will be "false"
+ * if present, because the CompatChanges#isChangeEnabled method returns true if the change id
+ * is not present.
+ */
+ @ChangeId
+ @Disabled
+ private static final long CAMERA_MIC_INDICATORS_NOT_PRESENT = 162547999L;
+
+ /**
* Revoke a set of runtime permissions for various apps.
*
* @param requests The permissions to revoke as {@code Map<packageName, List<permission>>}
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 0c190719af57..b9d27e923615 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -25,6 +25,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.IActivityManager;
@@ -637,24 +638,25 @@ public final class PermissionManager {
private static final class PackageNamePermissionQuery {
final String permName;
final String pkgName;
- final int uid;
+ final int userId;
- PackageNamePermissionQuery(@Nullable String permName, @Nullable String pkgName, int uid) {
+ PackageNamePermissionQuery(@Nullable String permName, @Nullable String pkgName,
+ @UserIdInt int userId) {
this.permName = permName;
this.pkgName = pkgName;
- this.uid = uid;
+ this.userId = userId;
}
@Override
public String toString() {
return String.format(
- "PackageNamePermissionQuery(pkgName=\"%s\", permName=\"%s, uid=%s\")",
- pkgName, permName, uid);
+ "PackageNamePermissionQuery(pkgName=\"%s\", permName=\"%s, userId=%s\")",
+ pkgName, permName, userId);
}
@Override
public int hashCode() {
- return Objects.hash(permName, pkgName, uid);
+ return Objects.hash(permName, pkgName, userId);
}
@Override
@@ -670,16 +672,16 @@ public final class PermissionManager {
}
return Objects.equals(permName, other.permName)
&& Objects.equals(pkgName, other.pkgName)
- && uid == other.uid;
+ && userId == other.userId;
}
}
/* @hide */
private static int checkPackageNamePermissionUncached(
- String permName, String pkgName, int uid) {
+ String permName, String pkgName, @UserIdInt int userId) {
try {
return ActivityThread.getPermissionManager().checkPermission(
- permName, pkgName, uid);
+ permName, pkgName, userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -693,7 +695,7 @@ public final class PermissionManager {
@Override
protected Integer recompute(PackageNamePermissionQuery query) {
return checkPackageNamePermissionUncached(
- query.permName, query.pkgName, query.uid);
+ query.permName, query.pkgName, query.userId);
}
};
@@ -702,9 +704,10 @@ public final class PermissionManager {
*
* @hide
*/
- public static int checkPackageNamePermission(String permName, String pkgName, int uid) {
+ public static int checkPackageNamePermission(String permName, String pkgName,
+ @UserIdInt int userId) {
return sPackageNamePermissionCache.query(
- new PackageNamePermissionQuery(permName, pkgName, uid));
+ new PackageNamePermissionQuery(permName, pkgName, userId));
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 660455e59a4a..7ad0e7d337d2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8974,6 +8974,14 @@ public final class Settings {
public static final String MEDIA_CONTROLS_RESUME = "qs_media_resumption";
/**
+ * Controls which packages are blocked from persisting in media controls when resumption is
+ * enabled. The list of packages is set by the user in the Settings app.
+ * @see Settings.Secure#MEDIA_CONTROLS_RESUME
+ * @hide
+ */
+ public static final String MEDIA_CONTROLS_RESUME_BLOCKED = "qs_media_resumption_blocked";
+
+ /**
* Controls if window magnification is enabled.
* @hide
*/
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index c1998c6009cf..82f60366a814 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -69,7 +69,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
}
public void onServedEditorChanged(EditorInfo info) {
- if (isDummyOrEmptyEditor(info)) {
+ if (isFallbackOrEmptyEditor(info)) {
mShowOnNextImeRender = false;
}
mFocusedEditor = info;
@@ -167,15 +167,15 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
}
}
- private boolean isDummyOrEmptyEditor(EditorInfo info) {
- // TODO(b/123044812): Handle dummy input gracefully in IME Insets API
+ private boolean isFallbackOrEmptyEditor(EditorInfo info) {
+ // TODO(b/123044812): Handle fallback input gracefully in IME Insets API
return info == null || (info.fieldId <= 0 && info.inputType <= 0);
}
private boolean isServedEditorRendered() {
if (mFocusedEditor == null || mPreRenderedEditor == null
- || isDummyOrEmptyEditor(mFocusedEditor)
- || isDummyOrEmptyEditor(mPreRenderedEditor)) {
+ || isFallbackOrEmptyEditor(mFocusedEditor)
+ || isFallbackOrEmptyEditor(mPreRenderedEditor)) {
// No view is focused or ready.
return false;
}
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index bf94670e1ca3..6136a80978b7 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -52,14 +52,12 @@ public class NotificationHeaderView extends ViewGroup {
private View mHeaderText;
private View mSecondaryHeaderText;
private OnClickListener mExpandClickListener;
- private OnClickListener mAppOpsListener;
private OnClickListener mFeedbackListener;
private HeaderTouchListener mTouchListener = new HeaderTouchListener();
private LinearLayout mTransferChip;
private NotificationExpandButton mExpandButton;
private CachingIconView mIcon;
private View mProfileBadge;
- private View mAppOps;
private View mFeedbackIcon;
private boolean mExpanded;
private boolean mShowExpandButtonAtEnd;
@@ -117,7 +115,6 @@ public class NotificationHeaderView extends ViewGroup {
mExpandButton = findViewById(com.android.internal.R.id.expand_button);
mIcon = findViewById(com.android.internal.R.id.icon);
mProfileBadge = findViewById(com.android.internal.R.id.profile_badge);
- mAppOps = findViewById(com.android.internal.R.id.app_ops);
mFeedbackIcon = findViewById(com.android.internal.R.id.feedback);
}
@@ -146,7 +143,6 @@ public class NotificationHeaderView extends ViewGroup {
// Icons that should go at the end
if ((child == mExpandButton && mShowExpandButtonAtEnd)
|| child == mProfileBadge
- || child == mAppOps
|| child == mFeedbackIcon
|| child == mTransferChip) {
iconWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth();
@@ -212,7 +208,6 @@ public class NotificationHeaderView extends ViewGroup {
// Icons that should go at the end
if ((child == mExpandButton && mShowExpandButtonAtEnd)
|| child == mProfileBadge
- || child == mAppOps
|| child == mFeedbackIcon
|| child == mTransferChip) {
if (end == getMeasuredWidth()) {
@@ -282,7 +277,7 @@ public class NotificationHeaderView extends ViewGroup {
}
private void updateTouchListener() {
- if (mExpandClickListener == null && mAppOpsListener == null && mFeedbackListener == null) {
+ if (mExpandClickListener == null && mFeedbackListener == null) {
setOnTouchListener(null);
return;
}
@@ -291,14 +286,6 @@ public class NotificationHeaderView extends ViewGroup {
}
/**
- * Sets onclick listener for app ops icons.
- */
- public void setAppOpsOnClickListener(OnClickListener l) {
- mAppOpsListener = l;
- updateTouchListener();
- }
-
- /**
* Sets onclick listener for feedback icon.
*/
public void setFeedbackOnClickListener(OnClickListener l) {
@@ -394,7 +381,6 @@ public class NotificationHeaderView extends ViewGroup {
private final ArrayList<Rect> mTouchRects = new ArrayList<>();
private Rect mExpandButtonRect;
- private Rect mAppOpsRect;
private Rect mFeedbackRect;
private int mTouchSlop;
private boolean mTrackGesture;
@@ -408,9 +394,7 @@ public class NotificationHeaderView extends ViewGroup {
mTouchRects.clear();
addRectAroundView(mIcon);
mExpandButtonRect = addRectAroundView(mExpandButton);
- mAppOpsRect = addRectAroundView(mAppOps);
mFeedbackRect = addRectAroundView(mFeedbackIcon);
- setTouchDelegate(new TouchDelegate(mAppOpsRect, mAppOps));
addWidthRect();
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
@@ -471,11 +455,7 @@ public class NotificationHeaderView extends ViewGroup {
break;
case MotionEvent.ACTION_UP:
if (mTrackGesture) {
- if (mAppOps.isVisibleToUser() && (mAppOpsRect.contains((int) x, (int) y)
- || mAppOpsRect.contains((int) mDownX, (int) mDownY))) {
- mAppOps.performClick();
- return true;
- } else if (mFeedbackIcon.isVisibleToUser()
+ if (mFeedbackIcon.isVisibleToUser()
&& (mFeedbackRect.contains((int) x, (int) y))
|| mFeedbackRect.contains((int) mDownX, (int) mDownY)) {
mFeedbackIcon.performClick();
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index d5d631ac1dc7..eef27262c699 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -54,7 +54,7 @@ public class BaseInputConnection implements InputConnection {
/** @hide */
protected final InputMethodManager mIMM;
final View mTargetView;
- final boolean mDummyMode;
+ final boolean mFallbackMode;
private Object[] mDefaultComposingSpans;
@@ -64,14 +64,14 @@ public class BaseInputConnection implements InputConnection {
BaseInputConnection(InputMethodManager mgr, boolean fullEditor) {
mIMM = mgr;
mTargetView = null;
- mDummyMode = !fullEditor;
+ mFallbackMode = !fullEditor;
}
public BaseInputConnection(View targetView, boolean fullEditor) {
mIMM = (InputMethodManager)targetView.getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
mTargetView = targetView;
- mDummyMode = !fullEditor;
+ mFallbackMode = !fullEditor;
}
public static final void removeComposingSpans(Spannable text) {
@@ -189,7 +189,7 @@ public class BaseInputConnection implements InputConnection {
/**
* Default implementation replaces any existing composing text with
- * the given text. In addition, only if dummy mode, a key event is
+ * the given text. In addition, only if fallback mode, a key event is
* sent for the new text and the current editable buffer cleared.
*/
public boolean commitText(CharSequence text, int newCursorPosition) {
@@ -445,7 +445,7 @@ public class BaseInputConnection implements InputConnection {
/**
* The default implementation removes the composing state from the
- * current editable text. In addition, only if dummy mode, a key event is
+ * current editable text. In addition, only if fallback mode, a key event is
* sent for the new text and the current editable buffer cleared.
*/
public boolean finishComposingText() {
@@ -454,7 +454,7 @@ public class BaseInputConnection implements InputConnection {
if (content != null) {
beginBatchEdit();
removeComposingSpans(content);
- // Note: sendCurrentText does nothing unless mDummyMode is set
+ // Note: sendCurrentText does nothing unless mFallbackMode is set
sendCurrentText();
endBatchEdit();
}
@@ -464,10 +464,10 @@ public class BaseInputConnection implements InputConnection {
/**
* The default implementation uses TextUtils.getCapsMode to get the
* cursor caps mode for the current selection position in the editable
- * text, unless in dummy mode in which case 0 is always returned.
+ * text, unless in fallback mode in which case 0 is always returned.
*/
public int getCursorCapsMode(int reqModes) {
- if (mDummyMode) return 0;
+ if (mFallbackMode) return 0;
final Editable content = getEditable();
if (content == null) return 0;
@@ -664,7 +664,7 @@ public class BaseInputConnection implements InputConnection {
content.setSpan(COMPOSING, a, b,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
- // Note: sendCurrentText does nothing unless mDummyMode is set
+ // Note: sendCurrentText does nothing unless mFallbackMode is set
sendCurrentText();
endBatchEdit();
}
@@ -715,7 +715,7 @@ public class BaseInputConnection implements InputConnection {
}
private void sendCurrentText() {
- if (!mDummyMode) {
+ if (!mFallbackMode) {
return;
}
diff --git a/core/java/android/webkit/UserPackage.java b/core/java/android/webkit/UserPackage.java
index 556b24c94b36..2e5ee041e54c 100644
--- a/core/java/android/webkit/UserPackage.java
+++ b/core/java/android/webkit/UserPackage.java
@@ -99,7 +99,7 @@ public class UserPackage {
private static List<UserInfo> getAllUsers(Context context) {
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- return userManager.getUsers(false);
+ return userManager.getUsers();
}
}
diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java
index 330c15cc4614..c82a6564c1d7 100644
--- a/core/java/com/android/internal/util/Preconditions.java
+++ b/core/java/com/android/internal/util/Preconditions.java
@@ -187,6 +187,32 @@ public class Preconditions {
}
/**
+ * Ensures the truth of an expression involving whether the calling identity is authorized to
+ * call the calling method.
+ *
+ * @param expression a boolean expression
+ * @throws SecurityException if {@code expression} is false
+ */
+ public static void checkCallAuthorization(final boolean expression) {
+ if (!expression) {
+ throw new SecurityException("Calling identity is not authorized");
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving whether the calling user is authorized to
+ * call the calling method.
+ *
+ * @param expression a boolean expression
+ * @throws SecurityException if {@code expression} is false
+ */
+ public static void checkCallingUser(final boolean expression) {
+ if (!expression) {
+ throw new SecurityException("Calling user is not authorized");
+ }
+ }
+
+ /**
* Check the requested flags, throwing if any requested flags are outside
* the allowed set.
*
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 3332143251fc..289a36f5380d 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -168,8 +168,6 @@ public class ConversationLayout extends FrameLayout
private int mFacePileProtectionWidthExpanded;
private boolean mImportantConversation;
private TextView mUnreadBadge;
- private ViewGroup mAppOps;
- private Rect mAppOpsTouchRect = new Rect();
private View mFeedbackIcon;
private float mMinTouchSize;
private Icon mConversationIcon;
@@ -214,7 +212,6 @@ public class ConversationLayout extends FrameLayout
mConversationIconView = findViewById(R.id.conversation_icon);
mConversationIconContainer = findViewById(R.id.conversation_icon_container);
mIcon = findViewById(R.id.icon);
- mAppOps = findViewById(com.android.internal.R.id.app_ops);
mFeedbackIcon = findViewById(com.android.internal.R.id.feedback);
mMinTouchSize = 48 * getResources().getDisplayMetrics().density;
mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring);
@@ -1174,43 +1171,6 @@ public class ConversationLayout extends FrameLayout
});
}
mTouchDelegate.clear();
- if (mAppOps.getWidth() > 0) {
-
- // Let's increase the touch size of the app ops view if it's here
- mAppOpsTouchRect.set(
- mAppOps.getLeft(),
- mAppOps.getTop(),
- mAppOps.getRight(),
- mAppOps.getBottom());
- for (int i = 0; i < mAppOps.getChildCount(); i++) {
- View child = mAppOps.getChildAt(i);
- if (child.getVisibility() == GONE) {
- continue;
- }
- // Make sure each child has at least a minTouchSize touch target around it
- float childTouchLeft = child.getLeft() + child.getWidth() / 2.0f
- - mMinTouchSize / 2.0f;
- float childTouchRight = childTouchLeft + mMinTouchSize;
- mAppOpsTouchRect.left = (int) Math.min(mAppOpsTouchRect.left,
- mAppOps.getLeft() + childTouchLeft);
- mAppOpsTouchRect.right = (int) Math.max(mAppOpsTouchRect.right,
- mAppOps.getLeft() + childTouchRight);
- }
-
- // Increase the height
- int heightIncrease = 0;
- if (mAppOpsTouchRect.height() < mMinTouchSize) {
- heightIncrease = (int) Math.ceil((mMinTouchSize - mAppOpsTouchRect.height())
- / 2.0f);
- }
- mAppOpsTouchRect.inset(0, -heightIncrease);
-
- getRelativeTouchRect(mAppOpsTouchRect, mAppOps);
-
- // Extend the size of the app opps to be at least 48dp
- mTouchDelegate.add(new TouchDelegate(mAppOpsTouchRect, mAppOps));
-
- }
if (mFeedbackIcon.getVisibility() == VISIBLE) {
updateFeedbackIconMargins();
float width = Math.max(mMinTouchSize, mFeedbackIcon.getWidth());
@@ -1240,13 +1200,7 @@ public class ConversationLayout extends FrameLayout
private void updateFeedbackIconMargins() {
MarginLayoutParams lp = (MarginLayoutParams) mFeedbackIcon.getLayoutParams();
- if (mAppOps.getWidth() == 0) {
- lp.setMarginStart(mNotificationHeaderSeparatingMargin);
- } else {
- float width = Math.max(mMinTouchSize, mFeedbackIcon.getWidth());
- int horizontalMargin = (int) ((width - mFeedbackIcon.getWidth()) / 2);
- lp.setMarginStart(horizontalMargin);
- }
+ lp.setMarginStart(mNotificationHeaderSeparatingMargin);
mFeedbackIcon.setLayoutParams(lp);
}
diff --git a/core/jni/android_media_AudioDeviceAttributes.cpp b/core/jni/android_media_AudioDeviceAttributes.cpp
index e79c95edbeb5..2a16dce99125 100644
--- a/core/jni/android_media_AudioDeviceAttributes.cpp
+++ b/core/jni/android_media_AudioDeviceAttributes.cpp
@@ -31,7 +31,7 @@ jint createAudioDeviceAttributesFromNative(JNIEnv *env, jobject *jAudioDeviceAtt
const AudioDeviceTypeAddr *devTypeAddr) {
jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
jint jNativeType = (jint)devTypeAddr->mType;
- ScopedLocalRef<jstring> jAddress(env, env->NewStringUTF(devTypeAddr->mAddress.data()));
+ ScopedLocalRef<jstring> jAddress(env, env->NewStringUTF(devTypeAddr->getAddress()));
*jAudioDeviceAttributes = env->NewObject(gAudioDeviceAttributesClass, gAudioDeviceAttributesCstor,
jNativeType, jAddress.get());
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 1f625443c96e..3f39478ffd43 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -172,6 +172,8 @@ static struct {
jmethodID postRecordConfigEventFromNative;
} gAudioPolicyEventHandlerMethods;
+static struct { jmethodID add; } gListMethods;
+
//
// JNI Initialization for OpenSLES routing
//
@@ -310,7 +312,7 @@ static int _check_AudioSystem_Command(const char* caller, status_t status)
static jint getVectorOfAudioDeviceTypeAddr(JNIEnv *env, jintArray deviceTypes,
jobjectArray deviceAddresses,
- Vector<AudioDeviceTypeAddr> &audioDeviceTypeAddrVector) {
+ AudioDeviceTypeAddrVector &audioDeviceTypeAddrVector) {
if (deviceTypes == nullptr || deviceAddresses == nullptr) {
return (jint)AUDIO_JAVA_BAD_VALUE;
}
@@ -337,7 +339,7 @@ static jint getVectorOfAudioDeviceTypeAddr(JNIEnv *env, jintArray deviceTypes,
}
const char *address = env->GetStringUTFChars((jstring)addrJobj, NULL);
AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address);
- audioDeviceTypeAddrVector.add(dev);
+ audioDeviceTypeAddrVector.push_back(dev);
env->ReleaseStringUTFChars((jstring)addrJobj, address);
}
env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0);
@@ -2062,7 +2064,7 @@ exit:
static jint android_media_AudioSystem_setUidDeviceAffinities(JNIEnv *env, jobject clazz,
jint uid, jintArray deviceTypes, jobjectArray deviceAddresses) {
- Vector<AudioDeviceTypeAddr> deviceVector;
+ AudioDeviceTypeAddrVector deviceVector;
jint results = getVectorOfAudioDeviceTypeAddr(env, deviceTypes, deviceAddresses, deviceVector);
if (results != NO_ERROR) {
return results;
@@ -2080,7 +2082,7 @@ static jint android_media_AudioSystem_removeUidDeviceAffinities(JNIEnv *env, job
static jint android_media_AudioSystem_setUserIdDeviceAffinities(JNIEnv *env, jobject clazz,
jint userId, jintArray deviceTypes,
jobjectArray deviceAddresses) {
- Vector<AudioDeviceTypeAddr> deviceVector;
+ AudioDeviceTypeAddrVector deviceVector;
jint results = getVectorOfAudioDeviceTypeAddr(env, deviceTypes, deviceAddresses, deviceVector);
if (results != NO_ERROR) {
return results;
@@ -2361,46 +2363,48 @@ android_media_AudioSystem_isCallScreeningModeSupported(JNIEnv *env, jobject thiz
return AudioSystem::isCallScreenModeSupported();
}
-static jint
-android_media_AudioSystem_setPreferredDeviceForStrategy(JNIEnv *env, jobject thiz,
- jint strategy, jint deviceType, jstring deviceAddress) {
-
- const char *c_address = env->GetStringUTFChars(deviceAddress, NULL);
+static jint android_media_AudioSystem_setDevicesRoleForStrategy(JNIEnv *env, jobject thiz,
+ jint strategy, jint role,
+ jintArray jDeviceTypes,
+ jobjectArray jDeviceAddresses) {
+ AudioDeviceTypeAddrVector nDevices;
+ jint results = getVectorOfAudioDeviceTypeAddr(env, jDeviceTypes, jDeviceAddresses, nDevices);
+ if (results != NO_ERROR) {
+ return results;
+ }
int status = check_AudioSystem_Command(
- AudioSystem::setPreferredDeviceForStrategy((product_strategy_t) strategy,
- AudioDeviceTypeAddr(deviceType, c_address)));
- env->ReleaseStringUTFChars(deviceAddress, c_address);
+ AudioSystem::setDevicesRoleForStrategy((product_strategy_t)strategy,
+ (device_role_t)role, nDevices));
return (jint) status;
}
-static jint
-android_media_AudioSystem_removePreferredDeviceForStrategy(JNIEnv *env, jobject thiz, jint strategy)
-{
- return (jint) check_AudioSystem_Command(
- AudioSystem::removePreferredDeviceForStrategy((product_strategy_t) strategy));
+static jint android_media_AudioSystem_removeDevicesRoleForStrategy(JNIEnv *env, jobject thiz,
+ jint strategy, jint role) {
+ return (jint)check_AudioSystem_Command(
+ AudioSystem::removeDevicesRoleForStrategy((product_strategy_t)strategy,
+ (device_role_t)role));
}
-static jint
-android_media_AudioSystem_getPreferredDeviceForStrategy(JNIEnv *env, jobject thiz,
- jint strategy, jobjectArray jDeviceArray)
-{
- if (jDeviceArray == nullptr || env->GetArrayLength(jDeviceArray) != 1) {
- ALOGE("%s invalid array to store AudioDeviceAttributes", __FUNCTION__);
- return (jint)AUDIO_JAVA_BAD_VALUE;
- }
-
- AudioDeviceTypeAddr elDevice;
+static jint android_media_AudioSystem_getDevicesForRoleAndStrategy(JNIEnv *env, jobject thiz,
+ jint strategy, jint role,
+ jobject jDevices) {
+ AudioDeviceTypeAddrVector nDevices;
status_t status = check_AudioSystem_Command(
- AudioSystem::getPreferredDeviceForStrategy((product_strategy_t) strategy, elDevice));
+ AudioSystem::getDevicesForRoleAndStrategy((product_strategy_t)strategy,
+ (device_role_t)role, nDevices));
if (status != NO_ERROR) {
return (jint) status;
}
- jobject jAudioDeviceAttributes = NULL;
- jint jStatus = createAudioDeviceAttributesFromNative(env, &jAudioDeviceAttributes, &elDevice);
- if (jStatus == AUDIO_JAVA_SUCCESS) {
- env->SetObjectArrayElement(jDeviceArray, 0, jAudioDeviceAttributes);
+ for (const auto &device : nDevices) {
+ jobject jAudioDeviceAttributes = NULL;
+ jint jStatus = createAudioDeviceAttributesFromNative(env, &jAudioDeviceAttributes, &device);
+ if (jStatus != AUDIO_JAVA_SUCCESS) {
+ return jStatus;
+ }
+ env->CallBooleanMethod(jDevices, gListMethods.add, jAudioDeviceAttributes);
+ env->DeleteLocalRef(jAudioDeviceAttributes);
}
- return jStatus;
+ return AUDIO_JAVA_SUCCESS;
}
static jint
@@ -2548,12 +2552,12 @@ static const JNINativeMethod gMethods[] =
{"setAudioHalPids", "([I)I", (void *)android_media_AudioSystem_setAudioHalPids},
{"isCallScreeningModeSupported", "()Z",
(void *)android_media_AudioSystem_isCallScreeningModeSupported},
- {"setPreferredDeviceForStrategy", "(IILjava/lang/String;)I",
- (void *)android_media_AudioSystem_setPreferredDeviceForStrategy},
- {"removePreferredDeviceForStrategy", "(I)I",
- (void *)android_media_AudioSystem_removePreferredDeviceForStrategy},
- {"getPreferredDeviceForStrategy", "(I[Landroid/media/AudioDeviceAttributes;)I",
- (void *)android_media_AudioSystem_getPreferredDeviceForStrategy},
+ {"setDevicesRoleForStrategy", "(II[I[Ljava/lang/String;)I",
+ (void *)android_media_AudioSystem_setDevicesRoleForStrategy},
+ {"removeDevicesRoleForStrategy", "(II)I",
+ (void *)android_media_AudioSystem_removeDevicesRoleForStrategy},
+ {"getDevicesForRoleAndStrategy", "(IILjava/util/List;)I",
+ (void *)android_media_AudioSystem_getDevicesForRoleAndStrategy},
{"getDevicesForAttributes",
"(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;)I",
(void *)android_media_AudioSystem_getDevicesForAttributes},
@@ -2755,6 +2759,9 @@ int register_android_media_AudioSystem(JNIEnv *env)
gMidAudioRecordRoutingProxy_release =
android::GetMethodIDOrDie(env, gClsAudioRecordRoutingProxy, "native_release", "()V");
+ jclass listClass = FindClassOrDie(env, "java/util/List");
+ gListMethods.add = GetMethodIDOrDie(env, listClass, "add", "(Ljava/lang/Object;)Z");
+
AudioSystem::addErrorCallback(android_media_AudioSystem_error_callback);
RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 1014fbb73877..0d65bd1cf9bb 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -744,6 +744,41 @@ enum Action {
// CATEGORY: SETTINGS
// OS: R
ACTION_CONFIRM_SIM_DELETION_OFF = 1739;
+
+ // ACTION: Settings > System > Gestures > Double tap > Toggle on Double tap
+ // CATEGORY: SETTINGS
+ // OS: S
+ ACTION_COLUMBUS_ENABLED = 1740;
+
+ // ACTION: Settings > System > Gestures > Double tap > Toggle off Double tap
+ // CATEGORY: SETTINGS
+ // OS: S
+ ACTION_COLUMBUS_DISABLED = 1741;
+
+ // ACTION: Settings > System > Gestures > Double tap > Invoke Assistant
+ // CATEGORY: SETTINGS
+ // OS: S
+ ACTION_COLUMBUS_ACTION_ASSISTANT = 1742;
+
+ // ACTION: Settings > System > Gestures > Double tap > Take screenshot
+ // CATEGORY: SETTINGS
+ // OS: S
+ ACTION_COLUMBUS_ACTION_SCREENSHOT = 1743;
+
+ // ACTION: Settings > System > Gestures > Double tap > Play and pause
+ // CATEGORY: SETTINGS
+ // OS: S
+ ACTION_COLUMBUS_ACTION_PLAY_PAUSE = 1744;
+
+ // ACTION: Settings > System > Gestures > Double tap > Open app overview
+ // CATEGORY: SETTINGS
+ // OS: S
+ ACTION_COLUMBUS_ACTION_OVERVIEW = 1745;
+
+ // ACTION: Settings > System > Gestures > Double tap > Open notification shade
+ // CATEGORY: SETTINGS
+ // OS: S
+ ACTION_COLUMBUS_ACTION_NOTIFICATION_SHADE = 1746;
}
/**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index edb972730f69..32c1e4a1411c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -558,6 +558,7 @@
<protected-broadcast android:name="android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED" />
<protected-broadcast android:name="android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED" />
<protected-broadcast android:name="android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED" />
+ <protected-broadcast android:name="android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED" />
<protected-broadcast android:name="android.app.action.APP_BLOCK_STATE_CHANGED" />
<protected-broadcast android:name="android.permission.GET_APP_GRANTED_URI_PERMISSIONS" />
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index d22a19faa52b..9a1b592c895a 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -160,43 +160,6 @@
android:visibility="gone"
android:contentDescription="@string/notification_work_profile_content_description"
/>
- <LinearLayout
- android:id="@+id/app_ops"
- android:layout_height="match_parent"
- android:layout_width="wrap_content"
- android:layout_marginStart="6dp"
- android:background="?android:selectableItemBackgroundBorderless"
- android:orientation="horizontal">
- <ImageView
- android:id="@+id/camera"
- android:layout_width="?attr/notificationHeaderIconSize"
- android:layout_height="?attr/notificationHeaderIconSize"
- android:src="@drawable/ic_camera"
- android:visibility="gone"
- android:focusable="false"
- android:contentDescription="@string/notification_appops_camera_active"
- />
- <ImageView
- android:id="@+id/mic"
- android:layout_width="?attr/notificationHeaderIconSize"
- android:layout_height="?attr/notificationHeaderIconSize"
- android:src="@drawable/ic_mic"
- android:layout_marginStart="4dp"
- android:visibility="gone"
- android:focusable="false"
- android:contentDescription="@string/notification_appops_microphone_active"
- />
- <ImageView
- android:id="@+id/overlay"
- android:layout_width="?attr/notificationHeaderIconSize"
- android:layout_height="?attr/notificationHeaderIconSize"
- android:src="@drawable/ic_alert_window_layer"
- android:layout_marginStart="4dp"
- android:visibility="gone"
- android:focusable="false"
- android:contentDescription="@string/notification_appops_overlay_active"
- />
- </LinearLayout>
<include
layout="@layout/notification_material_media_transfer_action"
android:id="@+id/media_seamless"
diff --git a/core/res/res/values/cross_profile_apps.xml b/core/res/res/values/cross_profile_apps.xml
index ab6f20db0694..3688c3eb940b 100644
--- a/core/res/res/values/cross_profile_apps.xml
+++ b/core/res/res/values/cross_profile_apps.xml
@@ -17,7 +17,7 @@
<resources>
<!--
A collection of apps that have been pre-approved for cross-profile communication.
- These will not require admin consent, but will still require user consent during provisioning.
+ These will not require admin or user consent.
-->
<string-array translatable="false" name="cross_profile_apps">
</string-array>
diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml
index d8ec72f33ddc..166edca3d046 100644
--- a/core/res/res/xml/power_profile.xml
+++ b/core/res/res/xml/power_profile.xml
@@ -20,7 +20,7 @@
<device name="Android">
<!-- Most values are the incremental current used by a feature,
in mA (measured at nominal voltage).
- The default values are deliberately incorrect dummy values.
+ The default values are deliberately incorrect values.
OEM's must measure and provide actual values before
shipping a device.
Example real-world values are given in comments, but they
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 000e870369db..896a53486311 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -25,14 +25,14 @@ import static android.view.Display.INVALID_DISPLAY;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.testng.Assert.assertFalse;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityThread;
+import android.app.ActivityThread.ActivityClientRecord;
import android.app.IApplicationThread;
import android.app.PictureInPictureParams;
import android.app.ResourcesManager;
@@ -114,11 +114,12 @@ public class ActivityThreadTest {
final ActivityThread activityThread = activity.getActivityThread();
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
activityThread.executeTransaction(newResumeTransaction(activity));
- assertNull(activityThread.performResumeActivity(activity.getActivityToken(),
- true /* finalStateRequest */, "test"));
+ final ActivityClientRecord r = getActivityClientRecord(activity);
+ assertFalse(activityThread.performResumeActivity(r, true /* finalStateRequest */,
+ "test"));
- assertNull(activityThread.performResumeActivity(activity.getActivityToken(),
- false /* finalStateRequest */, "test"));
+ assertFalse(activityThread.performResumeActivity(r, false /* finalStateRequest */,
+ "test"));
});
}
@@ -244,20 +245,18 @@ public class ActivityThreadTest {
newerConfig.orientation = orientation == ORIENTATION_LANDSCAPE
? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
newerConfig.seq = seq + 2;
- activityThread.updatePendingActivityConfiguration(activity.getActivityToken(),
- newerConfig);
+ final ActivityClientRecord r = getActivityClientRecord(activity);
+ activityThread.updatePendingActivityConfiguration(r, newerConfig);
final Configuration olderConfig = new Configuration();
olderConfig.orientation = orientation;
olderConfig.seq = seq + 1;
- activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
- olderConfig, INVALID_DISPLAY);
+ activityThread.handleActivityConfigurationChanged(r, olderConfig, INVALID_DISPLAY);
assertEquals(numOfConfig, activity.mNumOfConfigChanges);
assertEquals(olderConfig.orientation, activity.mConfig.orientation);
- activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
- newerConfig, INVALID_DISPLAY);
+ activityThread.handleActivityConfigurationChanged(r, newerConfig, INVALID_DISPLAY);
assertEquals(numOfConfig + 1, activity.mNumOfConfigChanges);
assertEquals(newerConfig.orientation, activity.mConfig.orientation);
});
@@ -274,7 +273,7 @@ public class ActivityThreadTest {
config.seq = BASE_SEQ;
config.orientation = ORIENTATION_PORTRAIT;
- activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
+ activityThread.handleActivityConfigurationChanged(getActivityClientRecord(activity),
config, INVALID_DISPLAY);
});
@@ -335,8 +334,8 @@ public class ActivityThreadTest {
config.seq = BASE_SEQ;
config.orientation = ORIENTATION_PORTRAIT;
- activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
- config, INVALID_DISPLAY);
+ final ActivityClientRecord r = getActivityClientRecord(activity);
+ activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
});
final int numOfConfig = activity.mNumOfConfigChanges;
@@ -513,9 +512,10 @@ public class ActivityThreadTest {
startIntent.putExtra(TestActivity.PIP_REQUESTED_OVERRIDE_ENTER, true);
final TestActivity activity = mActivityTestRule.launchActivity(startIntent);
final ActivityThread activityThread = activity.getActivityThread();
+ final ActivityClientRecord r = getActivityClientRecord(activity);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- activityThread.handlePictureInPictureRequested(activity.getActivityToken());
+ activityThread.handlePictureInPictureRequested(r);
});
assertTrue(activity.pipRequested());
@@ -528,9 +528,10 @@ public class ActivityThreadTest {
startIntent.putExtra(TestActivity.PIP_REQUESTED_OVERRIDE_SKIP, true);
final TestActivity activity = mActivityTestRule.launchActivity(startIntent);
final ActivityThread activityThread = activity.getActivityThread();
+ final ActivityClientRecord r = getActivityClientRecord(activity);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- activityThread.handlePictureInPictureRequested(activity.getActivityToken());
+ activityThread.handlePictureInPictureRequested(r);
});
assertTrue(activity.pipRequested());
@@ -541,9 +542,10 @@ public class ActivityThreadTest {
public void testHandlePictureInPictureRequested_notOverridden() {
final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
final ActivityThread activityThread = activity.getActivityThread();
+ final ActivityClientRecord r = getActivityClientRecord(activity);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- activityThread.handlePictureInPictureRequested(activity.getActivityToken());
+ activityThread.handlePictureInPictureRequested(r);
});
assertTrue(activity.pipRequested());
@@ -552,8 +554,9 @@ public class ActivityThreadTest {
}
/**
- * Calls {@link ActivityThread#handleActivityConfigurationChanged(IBinder, Configuration, int)}
- * to try to push activity configuration to the activity for the given sequence number.
+ * Calls {@link ActivityThread#handleActivityConfigurationChanged(ActivityClientRecord,
+ * Configuration, int)} to try to push activity configuration to the activity for the given
+ * sequence number.
* <p>
* It uses orientation to push the configuration and it tries a different orientation if the
* first attempt doesn't make through, to rule out the possibility that the previous
@@ -566,13 +569,13 @@ public class ActivityThreadTest {
*/
private int applyConfigurationChange(TestActivity activity, int seq) {
final ActivityThread activityThread = activity.getActivityThread();
+ final ActivityClientRecord r = getActivityClientRecord(activity);
final int numOfConfig = activity.mNumOfConfigChanges;
Configuration config = new Configuration();
config.orientation = ORIENTATION_PORTRAIT;
config.seq = seq;
- activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config,
- INVALID_DISPLAY);
+ activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
if (activity.mNumOfConfigChanges > numOfConfig) {
return config.seq;
@@ -581,12 +584,17 @@ public class ActivityThreadTest {
config = new Configuration();
config.orientation = ORIENTATION_LANDSCAPE;
config.seq = seq + 1;
- activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config,
- INVALID_DISPLAY);
+ activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
return config.seq;
}
+ private static ActivityClientRecord getActivityClientRecord(Activity activity) {
+ final ActivityThread thread = activity.getActivityThread();
+ final IBinder token = activity.getActivityToken();
+ return thread.getActivityClient(token);
+ }
+
private static ClientTransaction newRelaunchResumeTransaction(Activity activity) {
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(null,
null, 0, new MergedConfiguration(), false /* preserveWindow */);
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index 3c32c71cf961..6a0105cf7ff0 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -32,11 +32,12 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.Activity;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.app.servertransaction.ActivityLifecycleItem.LifecycleState;
@@ -225,6 +226,7 @@ public class TransactionExecutorTests {
when(callback2.getPostExecutionState()).thenReturn(UNDEFINED);
ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
IBinder token = mock(IBinder.class);
+ when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
token /* activityToken */);
@@ -236,9 +238,9 @@ public class TransactionExecutorTests {
mExecutor.execute(transaction);
InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, stateRequest);
- inOrder.verify(callback1, times(1)).execute(eq(mTransactionHandler), eq(token), any());
- inOrder.verify(callback2, times(1)).execute(eq(mTransactionHandler), eq(token), any());
- inOrder.verify(stateRequest, times(1)).execute(eq(mTransactionHandler), eq(token), any());
+ inOrder.verify(callback1).execute(eq(mTransactionHandler), eq(token), any());
+ inOrder.verify(callback2).execute(eq(mTransactionHandler), eq(token), any());
+ inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
}
@Test
@@ -273,7 +275,7 @@ public class TransactionExecutorTests {
// The launch transaction should not be executed because its token is in the
// to-be-destroyed container.
- verify(launchItem, times(0)).execute(any(), any(), any());
+ verify(launchItem, never()).execute(any(), any(), any());
// After the destroy transaction has been executed, the token should be removed.
mExecutor.execute(destroyTransaction);
@@ -282,6 +284,8 @@ public class TransactionExecutorTests {
@Test
public void testActivityResultRequiredStateResolution() {
+ when(mTransactionHandler.getActivity(any())).thenReturn(mock(Activity.class));
+
PostExecItem postExecItem = new PostExecItem(ON_RESUME);
IBinder token = mock(IBinder.class);
@@ -292,12 +296,12 @@ public class TransactionExecutorTests {
// Verify resolution that should get to onPause
mClientRecord.setState(ON_RESUME);
mExecutor.executeCallbacks(transaction);
- verify(mExecutor, times(1)).cycleToPath(eq(mClientRecord), eq(ON_PAUSE), eq(transaction));
+ verify(mExecutor).cycleToPath(eq(mClientRecord), eq(ON_PAUSE), eq(transaction));
// Verify resolution that should get to onStart
mClientRecord.setState(ON_STOP);
mExecutor.executeCallbacks(transaction);
- verify(mExecutor, times(1)).cycleToPath(eq(mClientRecord), eq(ON_START), eq(transaction));
+ verify(mExecutor).cycleToPath(eq(mClientRecord), eq(ON_START), eq(transaction));
}
@Test
@@ -433,6 +437,38 @@ public class TransactionExecutorTests {
mExecutorHelper.getClosestPreExecutionState(mClientRecord, ON_RESUME));
}
+ @Test(expected = IllegalArgumentException.class)
+ public void testActivityItemNullRecordThrowsException() {
+ final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
+ when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
+ final IBinder token = mock(IBinder.class);
+ final ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
+ token /* activityToken */);
+ transaction.addCallback(activityItem);
+ when(mTransactionHandler.getActivityClient(token)).thenReturn(null);
+
+ mExecutor.executeCallbacks(transaction);
+ }
+
+ @Test
+ public void testActivityItemExecute() {
+ final IBinder token = mock(IBinder.class);
+ final ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
+ token /* activityToken */);
+ final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
+ when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
+ transaction.addCallback(activityItem);
+ final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
+ transaction.setLifecycleStateRequest(stateRequest);
+ when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
+
+ mExecutor.execute(transaction);
+
+ final InOrder inOrder = inOrder(activityItem, stateRequest);
+ inOrder.verify(activityItem).execute(eq(mTransactionHandler), eq(mClientRecord), any());
+ inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
+ }
+
private static int[] shuffledArray(int[] inputArray) {
final List<Integer> list = Arrays.stream(inputArray).boxed().collect(Collectors.toList());
Collections.shuffle(list);
@@ -489,13 +525,13 @@ public class TransactionExecutorTests {
public static final Parcelable.Creator<StubItem> CREATOR =
new Parcelable.Creator<StubItem>() {
- public StubItem createFromParcel(Parcel in) {
- return new StubItem(in);
- }
-
- public StubItem[] newArray(int size) {
- return new StubItem[size];
- }
- };
+ public StubItem createFromParcel(Parcel in) {
+ return new StubItem(in);
+ }
+
+ public StubItem[] newArray(int size) {
+ return new StubItem[size];
+ }
+ };
}
}
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 1cdc75aa1f40..3f2d0f134443 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -176,27 +176,27 @@ public class ActivityThreadClientTest {
}
private void startActivity(ActivityClientRecord r) {
- mThread.handleStartActivity(r.token, null /* pendingActions */);
+ mThread.handleStartActivity(r, null /* pendingActions */);
}
private void resumeActivity(ActivityClientRecord r) {
- mThread.handleResumeActivity(r.token, true /* finalStateRequest */,
+ mThread.handleResumeActivity(r, true /* finalStateRequest */,
true /* isForward */, "test");
}
private void pauseActivity(ActivityClientRecord r) {
- mThread.handlePauseActivity(r.token, false /* finished */,
+ mThread.handlePauseActivity(r, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, null /* pendingActions */,
"test");
}
private void stopActivity(ActivityClientRecord r) {
- mThread.handleStopActivity(r.token, 0 /* configChanges */,
+ mThread.handleStopActivity(r, 0 /* configChanges */,
new PendingTransactionActions(), false /* finalStateRequest */, "test");
}
private void destroyActivity(ActivityClientRecord r) {
- mThread.handleDestroyActivity(r.token, true /* finishing */, 0 /* configChanges */,
+ mThread.handleDestroyActivity(r, true /* finishing */, 0 /* configChanges */,
false /* getNonConfigInstance */, "test");
}
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java
index ba3ebddd4b86..4ec752a6dd9e 100644
--- a/drm/java/android/drm/DrmManagerClient.java
+++ b/drm/java/android/drm/DrmManagerClient.java
@@ -751,7 +751,7 @@ public class DrmManagerClient implements AutoCloseable {
/**
* Removes all the rights information of every DRM plug-in (agent) associated with
- * the DRM framework. Will be used during a master reset.
+ * the DRM framework.
*
* @return ERROR_NONE for success; ERROR_UNKNOWN for failure.
*/
diff --git a/libs/hostgraphics/Android.bp b/libs/hostgraphics/Android.bp
index e713b98b867e..9d83e491fdc1 100644
--- a/libs/hostgraphics/Android.bp
+++ b/libs/hostgraphics/Android.bp
@@ -5,6 +5,10 @@ cc_library_host_static {
"-Wno-unused-parameter",
],
+ static_libs: [
+ "libbase",
+ ],
+
srcs: [
":libui_host_common",
"Fence.cpp",
@@ -28,4 +32,4 @@ cc_library_host_static {
enabled: true,
}
},
-} \ No newline at end of file
+}
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 2a8aa8c3e5b7..a11678189bad 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -238,12 +238,8 @@ EGLConfig EglManager::loadFP16Config(EGLDisplay display, SwapBehavior swapBehavi
return config;
}
-extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
-
void EglManager::initExtensions() {
auto extensions = StringUtils::split(eglQueryString(mEglDisplay, EGL_EXTENSIONS));
- auto extensionsAndroid =
- StringUtils::split(eglQueryStringImplementationANDROID(mEglDisplay, EGL_EXTENSIONS));
// For our purposes we don't care if EGL_BUFFER_AGE is a result of
// EGL_EXT_buffer_age or EGL_KHR_partial_update as our usage is covered
@@ -265,10 +261,7 @@ void EglManager::initExtensions() {
EglExtensions.surfacelessContext = extensions.has("EGL_KHR_surfaceless_context");
EglExtensions.fenceSync = extensions.has("EGL_KHR_fence_sync");
EglExtensions.waitSync = extensions.has("EGL_KHR_wait_sync");
-
- // EGL_ANDROID_native_fence_sync is not exposed to applications, so access
- // this through the private Android-specific query instead.
- EglExtensions.nativeFenceSync = extensionsAndroid.has("EGL_ANDROID_native_fence_sync");
+ EglExtensions.nativeFenceSync = extensions.has("EGL_ANDROID_native_fence_sync");
}
bool EglManager::hasEglContext() {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index b2e0538fd4b8..a16e063fe969 100755
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -75,6 +75,7 @@ import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -1599,11 +1600,25 @@ public class AudioManager {
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public boolean setPreferredDeviceForStrategy(@NonNull AudioProductStrategy strategy,
@NonNull AudioDeviceAttributes device) {
+ return setPreferredDevicesForStrategy(strategy, Arrays.asList(device));
+ }
+
+ /**
+ * @hide
+ * Removes the preferred audio device(s) previously set with
+ * {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)} or
+ * {@link #setPreferredDevicesForStrategy(AudioProductStrategy, List<AudioDeviceAttributes>)}.
+ * @param strategy the audio strategy whose routing will be affected
+ * @return true if the operation was successful, false otherwise (invalid strategy, or no
+ * device set for example)
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public boolean removePreferredDeviceForStrategy(@NonNull AudioProductStrategy strategy) {
Objects.requireNonNull(strategy);
- Objects.requireNonNull(device);
try {
final int status =
- getService().setPreferredDeviceForStrategy(strategy.getId(), device);
+ getService().removePreferredDevicesForStrategy(strategy.getId());
return status == AudioSystem.SUCCESS;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1612,19 +1627,52 @@ public class AudioManager {
/**
* @hide
- * Removes the preferred audio device previously set with
- * {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)}.
+ * Return the preferred device for an audio strategy, previously set with
+ * {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)} or
+ * {@link #setPreferredDevicesForStrategy(AudioProductStrategy, List<AudioDeviceAttributes>)}
+ * @param strategy the strategy to query
+ * @return the preferred device for that strategy, if multiple devices are set as preferred
+ * devices, the first one in the list will be returned. Null will be returned if none was
+ * ever set or if the strategy is invalid
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ @Nullable
+ public AudioDeviceAttributes getPreferredDeviceForStrategy(
+ @NonNull AudioProductStrategy strategy) {
+ List<AudioDeviceAttributes> devices = getPreferredDevicesForStrategy(strategy);
+ return devices.isEmpty() ? null : devices.get(0);
+ }
+
+ /**
+ * @hide
+ * Set the preferred devices for a given strategy, i.e. the audio routing to be used by
+ * this audio strategy. Note that the devices may not be available at the time the preferred
+ * devices is set, but it will be used once made available.
+ * <p>Use {@link #removePreferredDeviceForStrategy(AudioProductStrategy)} to cancel setting
+ * this preference for this strategy.</p>
+ * Note that the list of devices is not a list ranked by preference, but a list of one or more
+ * devices used simultaneously to output the same audio signal.
* @param strategy the audio strategy whose routing will be affected
- * @return true if the operation was successful, false otherwise (invalid strategy, or no
- * device set for example)
+ * @param devices a non-empty list of the audio devices to route to when available
+ * @return true if the operation was successful, false otherwise
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public boolean removePreferredDeviceForStrategy(@NonNull AudioProductStrategy strategy) {
+ public boolean setPreferredDevicesForStrategy(@NonNull AudioProductStrategy strategy,
+ @NonNull List<AudioDeviceAttributes> devices) {
Objects.requireNonNull(strategy);
+ Objects.requireNonNull(devices);
+ if (devices.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Tried to set preferred devices for strategy with a empty list");
+ }
+ for (AudioDeviceAttributes device : devices) {
+ Objects.requireNonNull(device);
+ }
try {
final int status =
- getService().removePreferredDeviceForStrategy(strategy.getId());
+ getService().setPreferredDevicesForStrategy(strategy.getId(), devices);
return status == AudioSystem.SUCCESS;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1633,19 +1681,21 @@ public class AudioManager {
/**
* @hide
- * Return the preferred device for an audio strategy, previously set with
+ * Return the preferred devices for an audio strategy, previously set with
* {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)}
+ * {@link #setPreferredDevicesForStrategy(AudioProductStrategy, List<AudioDeviceAttributes>)}
* @param strategy the strategy to query
* @return the preferred device for that strategy, or null if none was ever set or if the
* strategy is invalid
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public @Nullable AudioDeviceAttributes getPreferredDeviceForStrategy(
+ @NonNull
+ public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(
@NonNull AudioProductStrategy strategy) {
Objects.requireNonNull(strategy);
try {
- return getService().getPreferredDeviceForStrategy(strategy.getId());
+ return getService().getPreferredDevicesForStrategy(strategy.getId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1657,6 +1707,7 @@ public class AudioManager {
* strategy.
* <p>Note that this listener will only be invoked whenever
* {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)} or
+ * {@link #setPreferredDevicesForStrategy(AudioProductStrategy, List<AudioDeviceAttributes>)}
* {@link #removePreferredDeviceForStrategy(AudioProductStrategy)} causes a change in
* preferred device. It will not be invoked directly after registration with
* {@link #addOnPreferredDeviceForStrategyChangedListener(Executor, OnPreferredDeviceForStrategyChangedListener)}
@@ -1664,8 +1715,10 @@ public class AudioManager {
* @see #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
* @see #removePreferredDeviceForStrategy(AudioProductStrategy)
* @see #getPreferredDeviceForStrategy(AudioProductStrategy)
+ * @deprecated use #OnPreferredDevicesForStrategyChangedListener
*/
@SystemApi
+ @Deprecated
public interface OnPreferredDeviceForStrategyChangedListener {
/**
* Called on the listener to indicate that the preferred audio device for the given
@@ -1680,23 +1733,87 @@ public class AudioManager {
/**
* @hide
+ * Interface to be notified of changes in the preferred audio devices set for a given audio
+ * strategy.
+ * <p>Note that this listener will only be invoked whenever
+ * {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)} or
+ * {@link #setPreferredDevicesForStrategy(AudioProductStrategy, List<AudioDeviceAttributes>)}
+ * {@link #removePreferredDeviceForStrategy(AudioProductStrategy)} causes a change in
+ * preferred device(s). It will not be invoked directly after registration with
+ * {@link #addOnPreferredDevicesForStrategyChangedListener(
+ * Executor, OnPreferredDevicesForStrategyChangedListener)}
+ * to indicate which strategies had preferred devices at the time of registration.</p>
+ * @see #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
+ * @see #setPreferredDevicesForStrategy(AudioProductStrategy, List)
+ * @see #removePreferredDeviceForStrategy(AudioProductStrategy)
+ * @see #getPreferredDeviceForStrategy(AudioProductStrategy)
+ * @see #getPreferredDevicesForStrategy(AudioProductStrategy)
+ */
+ @SystemApi
+ public interface OnPreferredDevicesForStrategyChangedListener {
+ /**
+ * Called on the listener to indicate that the preferred audio devices for the given
+ * strategy has changed.
+ * @param strategy the {@link AudioProductStrategy} whose preferred device changed
+ * @param devices a list of newly set preferred audio devices
+ */
+ void onPreferredDevicesForStrategyChanged(@NonNull AudioProductStrategy strategy,
+ @NonNull List<AudioDeviceAttributes> devices);
+ }
+
+ /**
+ * @hide
* Adds a listener for being notified of changes to the strategy-preferred audio device.
* @param executor
* @param listener
* @throws SecurityException if the caller doesn't hold the required permission
+ * @deprecated use {@link #addOnPreferredDevicesForStrategyChangedListener(
+ * Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener)} instead
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ @Deprecated
public void addOnPreferredDeviceForStrategyChangedListener(
@NonNull @CallbackExecutor Executor executor,
@NonNull OnPreferredDeviceForStrategyChangedListener listener)
throws SecurityException {
+ // No-op, the method is deprecated.
+ }
+
+ /**
+ * @hide
+ * Removes a previously added listener of changes to the strategy-preferred audio device.
+ * @param listener
+ * @deprecated use {@link #removeOnPreferredDevicesForStrategyChangedListener(
+ * AudioManager.OnPreferredDevicesForStrategyChangedListener)} instead
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ @Deprecated
+ public void removeOnPreferredDeviceForStrategyChangedListener(
+ @NonNull OnPreferredDeviceForStrategyChangedListener listener) {
+ // No-op, the method is deprecated.
+ }
+
+ /**
+ * @hide
+ * Adds a listener for being notified of changes to the strategy-preferred audio device.
+ * @param executor
+ * @param listener
+ * @throws SecurityException if the caller doesn't hold the required permission
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+ public void addOnPreferredDevicesForStrategyChangedListener(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnPreferredDevicesForStrategyChangedListener listener)
+ throws SecurityException {
Objects.requireNonNull(executor);
Objects.requireNonNull(listener);
synchronized (mPrefDevListenerLock) {
if (hasPrefDevListener(listener)) {
throw new IllegalArgumentException(
- "attempt to call addOnPreferredDeviceForStrategyChangedListener() "
+ "attempt to call addOnPreferredDevicesForStrategyChangedListener() "
+ "on a previously registered listener");
}
// lazy initialization of the list of strategy-preferred device listener
@@ -1708,10 +1825,10 @@ public class AudioManager {
if (oldCbCount == 0 && mPrefDevListeners.size() > 0) {
// register binder for callbacks
if (mPrefDevDispatcherStub == null) {
- mPrefDevDispatcherStub = new StrategyPreferredDeviceDispatcherStub();
+ mPrefDevDispatcherStub = new StrategyPreferredDevicesDispatcherStub();
}
try {
- getService().registerStrategyPreferredDeviceDispatcher(mPrefDevDispatcherStub);
+ getService().registerStrategyPreferredDevicesDispatcher(mPrefDevDispatcherStub);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1726,8 +1843,8 @@ public class AudioManager {
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
- public void removeOnPreferredDeviceForStrategyChangedListener(
- @NonNull OnPreferredDeviceForStrategyChangedListener listener) {
+ public void removeOnPreferredDevicesForStrategyChangedListener(
+ @NonNull OnPreferredDevicesForStrategyChangedListener listener) {
Objects.requireNonNull(listener);
synchronized (mPrefDevListenerLock) {
if (!removePrefDevListener(listener)) {
@@ -1738,7 +1855,7 @@ public class AudioManager {
if (mPrefDevListeners.size() == 0) {
// unregister binder for callbacks
try {
- getService().unregisterStrategyPreferredDeviceDispatcher(
+ getService().unregisterStrategyPreferredDevicesDispatcher(
mPrefDevDispatcherStub);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1760,23 +1877,23 @@ public class AudioManager {
private @Nullable ArrayList<PrefDevListenerInfo> mPrefDevListeners;
private static class PrefDevListenerInfo {
- final @NonNull OnPreferredDeviceForStrategyChangedListener mListener;
+ final @NonNull OnPreferredDevicesForStrategyChangedListener mListener;
final @NonNull Executor mExecutor;
- PrefDevListenerInfo(OnPreferredDeviceForStrategyChangedListener listener, Executor exe) {
+ PrefDevListenerInfo(OnPreferredDevicesForStrategyChangedListener listener, Executor exe) {
mListener = listener;
mExecutor = exe;
}
}
@GuardedBy("mPrefDevListenerLock")
- private StrategyPreferredDeviceDispatcherStub mPrefDevDispatcherStub;
+ private StrategyPreferredDevicesDispatcherStub mPrefDevDispatcherStub;
- private final class StrategyPreferredDeviceDispatcherStub
- extends IStrategyPreferredDeviceDispatcher.Stub {
+ private final class StrategyPreferredDevicesDispatcherStub
+ extends IStrategyPreferredDevicesDispatcher.Stub {
@Override
- public void dispatchPrefDeviceChanged(int strategyId,
- @Nullable AudioDeviceAttributes device) {
+ public void dispatchPrefDevicesChanged(int strategyId,
+ @NonNull List<AudioDeviceAttributes> devices) {
// make a shallow copy of listeners so callback is not executed under lock
final ArrayList<PrefDevListenerInfo> prefDevListeners;
synchronized (mPrefDevListenerLock) {
@@ -1791,7 +1908,7 @@ public class AudioManager {
try {
for (PrefDevListenerInfo info : prefDevListeners) {
info.mExecutor.execute(() ->
- info.mListener.onPreferredDeviceForStrategyChanged(strategy, device));
+ info.mListener.onPreferredDevicesForStrategyChanged(strategy, devices));
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -1801,7 +1918,7 @@ public class AudioManager {
@GuardedBy("mPrefDevListenerLock")
private @Nullable PrefDevListenerInfo getPrefDevListenerInfo(
- OnPreferredDeviceForStrategyChangedListener listener) {
+ OnPreferredDevicesForStrategyChangedListener listener) {
if (mPrefDevListeners == null) {
return null;
}
@@ -1814,7 +1931,7 @@ public class AudioManager {
}
@GuardedBy("mPrefDevListenerLock")
- private boolean hasPrefDevListener(OnPreferredDeviceForStrategyChangedListener listener) {
+ private boolean hasPrefDevListener(OnPreferredDevicesForStrategyChangedListener listener) {
return getPrefDevListenerInfo(listener) != null;
}
@@ -1822,7 +1939,7 @@ public class AudioManager {
/**
* @return true if the listener was removed from the list
*/
- private boolean removePrefDevListener(OnPreferredDeviceForStrategyChangedListener listener) {
+ private boolean removePrefDevListener(OnPreferredDevicesForStrategyChangedListener listener) {
final PrefDevListenerInfo infoToRemove = getPrefDevListenerInfo(listener);
if (infoToRemove != null) {
mPrefDevListeners.remove(infoToRemove);
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 5fe5c0580b0c..243ec1f1fcd0 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -32,6 +32,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -1377,6 +1378,11 @@ public class AudioSystem
/** @hide */ public static final int FOR_VIBRATE_RINGING = 7;
private static final int NUM_FORCE_USE = 8;
+ // Device role in audio policy
+ public static final int DEVICE_ROLE_NONE = 0;
+ public static final int DEVICE_ROLE_PREFERRED = 1;
+ public static final int DEVICE_ROLE_DISABLED = 2;
+
/** @hide */
public static String forceUseUsageToString(int usage) {
switch (usage) {
@@ -1697,47 +1703,58 @@ public class AudioSystem
/**
* @hide
- * Sets the preferred device to use for a given audio strategy in the audio policy engine
+ * Set device as role for product strategy.
* @param strategy the id of the strategy to configure
- * @param device the device type and address to route to when available
+ * @param role the role of the devices
+ * @param devices the list of devices to be set as role for the given strategy
* @return {@link #SUCCESS} if successfully set
*/
- public static int setPreferredDeviceForStrategy(
- int strategy, @NonNull AudioDeviceAttributes device) {
- return setPreferredDeviceForStrategy(strategy,
- AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType()),
- device.getAddress());
+ public static int setDevicesRoleForStrategy(
+ int strategy, int role, @NonNull List<AudioDeviceAttributes> devices) {
+ if (devices.isEmpty()) {
+ return BAD_VALUE;
+ }
+ int[] types = new int[devices.size()];
+ String[] addresses = new String[devices.size()];
+ for (int i = 0; i < devices.size(); ++i) {
+ types[i] = AudioDeviceInfo.convertDeviceTypeToInternalDevice(devices.get(i).getType());
+ addresses[i] = devices.get(i).getAddress();
+ }
+ return setDevicesRoleForStrategy(strategy, role, types, addresses);
}
+
/**
* @hide
- * Set device routing per product strategy.
+ * Set device as role for product strategy.
* @param strategy the id of the strategy to configure
- * @param deviceType the native device type, NOT AudioDeviceInfo types
- * @param deviceAddress the address of the device
+ * @param role the role of the devices
+ * @param types all device types
+ * @param addresses all device addresses
* @return {@link #SUCCESS} if successfully set
*/
- private static native int setPreferredDeviceForStrategy(
- int strategy, int deviceType, String deviceAddress);
+ private static native int setDevicesRoleForStrategy(
+ int strategy, int role, @NonNull int[] types, @NonNull String[] addresses);
/**
* @hide
- * Remove preferred routing for the strategy
+ * Remove devices as role for the strategy
* @param strategy the id of the strategy to configure
+ * @param role the role of the devices
* @return {@link #SUCCESS} if successfully removed
*/
- public static native int removePreferredDeviceForStrategy(int strategy);
+ public static native int removeDevicesRoleForStrategy(int strategy, int role);
/**
* @hide
- * Query previously set preferred device for a strategy
+ * Query previously set devices as role for a strategy
* @param strategy the id of the strategy to query for
- * @param device an array of size 1 that will contain the preferred device, or null if
- * none was set
+ * @param role the role of the devices
+ * @param devices a list that will contain the devices of role
* @return {@link #SUCCESS} if there is a preferred device and it was successfully retrieved
* and written to the array
*/
- public static native int getPreferredDeviceForStrategy(int strategy,
- AudioDeviceAttributes[] device);
+ public static native int getDevicesForRoleAndStrategy(
+ int strategy, int role, @NonNull List<AudioDeviceAttributes> devices);
// Items shared with audio service
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 4cf236a84eb0..ef8b0edb1fe5 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -29,7 +29,7 @@ import android.media.IAudioServerStateDispatcher;
import android.media.IPlaybackConfigDispatcher;
import android.media.IRecordingConfigDispatcher;
import android.media.IRingtonePlayer;
-import android.media.IStrategyPreferredDeviceDispatcher;
+import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.IVolumeController;
import android.media.IVolumeController;
import android.media.PlayerBase;
@@ -279,11 +279,11 @@ interface IAudioService {
boolean isCallScreeningModeSupported();
- int setPreferredDeviceForStrategy(in int strategy, in AudioDeviceAttributes device);
+ int setPreferredDevicesForStrategy(in int strategy, in List<AudioDeviceAttributes> device);
- int removePreferredDeviceForStrategy(in int strategy);
+ int removePreferredDevicesForStrategy(in int strategy);
- AudioDeviceAttributes getPreferredDeviceForStrategy(in int strategy);
+ List<AudioDeviceAttributes> getPreferredDevicesForStrategy(in int strategy);
List<AudioDeviceAttributes> getDevicesForAttributes(in AudioAttributes attributes);
@@ -291,10 +291,10 @@ interface IAudioService {
int getAllowedCapturePolicy();
- void registerStrategyPreferredDeviceDispatcher(IStrategyPreferredDeviceDispatcher dispatcher);
+ void registerStrategyPreferredDevicesDispatcher(IStrategyPreferredDevicesDispatcher dispatcher);
- oneway void unregisterStrategyPreferredDeviceDispatcher(
- IStrategyPreferredDeviceDispatcher dispatcher);
+ oneway void unregisterStrategyPreferredDevicesDispatcher(
+ IStrategyPreferredDevicesDispatcher dispatcher);
oneway void setRttEnabled(in boolean rttEnabled);
diff --git a/media/java/android/media/IStrategyPreferredDeviceDispatcher.aidl b/media/java/android/media/IStrategyPreferredDevicesDispatcher.aidl
index b1f99e6b729e..db674c36a5c9 100644
--- a/media/java/android/media/IStrategyPreferredDeviceDispatcher.aidl
+++ b/media/java/android/media/IStrategyPreferredDevicesDispatcher.aidl
@@ -19,12 +19,12 @@ package android.media;
import android.media.AudioDeviceAttributes;
/**
- * AIDL for AudioService to signal audio strategy-preferred device updates.
+ * AIDL for AudioService to signal audio strategy-preferred devices updates.
*
* {@hide}
*/
-oneway interface IStrategyPreferredDeviceDispatcher {
+oneway interface IStrategyPreferredDevicesDispatcher {
- void dispatchPrefDeviceChanged(int strategyId, in AudioDeviceAttributes device);
+ void dispatchPrefDevicesChanged(int strategyId, in List<AudioDeviceAttributes> devices);
}
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index 39c7682a2a74..1386cba5f9ca 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -684,8 +684,15 @@ public abstract class MediaBrowserService extends Service {
List<MediaBrowser.MediaItem> filteredList =
(flag & RESULT_FLAG_OPTION_NOT_HANDLED) != 0
? applyOptions(list, options) : list;
- final ParceledListSlice<MediaBrowser.MediaItem> pls =
- filteredList == null ? null : new ParceledListSlice<>(filteredList);
+ final ParceledListSlice<MediaBrowser.MediaItem> pls;
+ if (filteredList == null) {
+ pls = null;
+ } else {
+ pls = new ParceledListSlice<>(filteredList);
+ // Limit the size of initial Parcel to prevent binder buffer overflow
+ // as onLoadChildren is an async binder call.
+ pls.setInlineCountLimit(1);
+ }
try {
connection.callbacks.onLoadChildren(parentId, pls, options);
} catch (RemoteException ex) {
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index 96961ac21a2d..45c49e58f390 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -333,7 +333,7 @@ android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_t
if (deviceType != AUDIO_DEVICE_NONE) {
device.mType = deviceType;
ScopedUtfChars address(env, deviceAddress);
- device.mAddress = address.c_str();
+ device.setAddress(address.c_str());
}
// create the native AudioEffect object
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index 51e7287bfd72..f9d0d14c7335 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -44126,7 +44126,9 @@ package android.telecom {
method public final void addExistingConnection(android.telecom.PhoneAccountHandle, android.telecom.Connection);
method public final void conferenceRemoteConnections(android.telecom.RemoteConnection, android.telecom.RemoteConnection);
method public final void connectionServiceFocusReleased();
+ method @Nullable public final android.telecom.RemoteConference createRemoteIncomingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
method public final android.telecom.RemoteConnection createRemoteIncomingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
+ method @Nullable public final android.telecom.RemoteConference createRemoteOutgoingConference(@Nullable android.telecom.PhoneAccountHandle, @Nullable android.telecom.ConnectionRequest);
method public final android.telecom.RemoteConnection createRemoteOutgoingConnection(android.telecom.PhoneAccountHandle, android.telecom.ConnectionRequest);
method public final java.util.Collection<android.telecom.Conference> getAllConferences();
method public final java.util.Collection<android.telecom.Connection> getAllConnections();
@@ -44357,6 +44359,7 @@ package android.telecom {
public final class RemoteConnection {
method public void abort();
+ method public void addConferenceParticipants(@NonNull java.util.List<android.net.Uri>);
method public void answer();
method public void disconnect();
method public android.net.Uri getAddress();
@@ -63867,7 +63870,7 @@ package java.lang.reflect {
package java.math {
- public class BigDecimal extends java.lang.Number implements java.lang.Comparable<java.math.BigDecimal> java.io.Serializable {
+ public class BigDecimal extends java.lang.Number implements java.lang.Comparable<java.math.BigDecimal> {
ctor public BigDecimal(char[], int, int);
ctor public BigDecimal(char[], int, int, java.math.MathContext);
ctor public BigDecimal(char[]);
@@ -63954,19 +63957,20 @@ package java.math {
field public static final java.math.BigDecimal ZERO;
}
- public class BigInteger extends java.lang.Number implements java.lang.Comparable<java.math.BigInteger> java.io.Serializable {
+ public class BigInteger extends java.lang.Number implements java.lang.Comparable<java.math.BigInteger> {
+ ctor public BigInteger(byte[]);
+ ctor public BigInteger(int, byte[]);
+ ctor public BigInteger(@NonNull String, int);
+ ctor public BigInteger(@NonNull String);
ctor public BigInteger(int, @NonNull java.util.Random);
ctor public BigInteger(int, int, @NonNull java.util.Random);
- ctor public BigInteger(@NonNull String);
- ctor public BigInteger(@NonNull String, int);
- ctor public BigInteger(int, byte[]);
- ctor public BigInteger(byte[]);
method @NonNull public java.math.BigInteger abs();
method @NonNull public java.math.BigInteger add(@NonNull java.math.BigInteger);
method @NonNull public java.math.BigInteger and(@NonNull java.math.BigInteger);
method @NonNull public java.math.BigInteger andNot(@NonNull java.math.BigInteger);
method public int bitCount();
method public int bitLength();
+ method public byte byteValueExact();
method @NonNull public java.math.BigInteger clearBit(int);
method public int compareTo(@NonNull java.math.BigInteger);
method @NonNull public java.math.BigInteger divide(@NonNull java.math.BigInteger);
@@ -63977,8 +63981,10 @@ package java.math {
method @NonNull public java.math.BigInteger gcd(@NonNull java.math.BigInteger);
method public int getLowestSetBit();
method public int intValue();
+ method public int intValueExact();
method public boolean isProbablePrime(int);
method public long longValue();
+ method public long longValueExact();
method @NonNull public java.math.BigInteger max(@NonNull java.math.BigInteger);
method @NonNull public java.math.BigInteger min(@NonNull java.math.BigInteger);
method @NonNull public java.math.BigInteger mod(@NonNull java.math.BigInteger);
@@ -63995,6 +64001,7 @@ package java.math {
method @NonNull public java.math.BigInteger setBit(int);
method @NonNull public java.math.BigInteger shiftLeft(int);
method @NonNull public java.math.BigInteger shiftRight(int);
+ method public short shortValueExact();
method public int signum();
method @NonNull public java.math.BigInteger subtract(@NonNull java.math.BigInteger);
method public boolean testBit(int);
diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt
index 35b483b9fb84..617a83f05791 100644
--- a/non-updatable-api/module-lib-current.txt
+++ b/non-updatable-api/module-lib-current.txt
@@ -7,6 +7,7 @@ package android.app {
public class NotificationManager {
method public boolean hasEnabledNotificationListener(@NonNull String, @NonNull android.os.UserHandle);
+ field public static final String ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED = "android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED";
}
}
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index cf792b6abbd2..dbf9e9fb4ae5 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -4136,7 +4136,8 @@ package android.media {
public class AudioManager {
method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
- method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException;
+ method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException;
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener) throws java.lang.SecurityException;
method public void clearAudioServerStateCallback();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
@@ -4148,13 +4149,15 @@ package android.media {
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMaxVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getMinVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.AudioDeviceAttributes getPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getSupportedSystemUsages();
method @IntRange(from=0) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int getVolumeIndexForAttributes(@NonNull android.media.AudioAttributes);
method public boolean isAudioServerRunning();
method public boolean isHdmiSystemAudioSupported();
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
method public void registerVolumeGroupCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.VolumeGroupCallback);
- method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean removePreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int, android.media.audiopolicy.AudioPolicy) throws java.lang.IllegalArgumentException;
@@ -4164,6 +4167,7 @@ package android.media {
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDevicesForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setSupportedSystemUsages(@NonNull int[]);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setVolumeIndexForAttributes(@NonNull android.media.AudioAttributes, int, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
@@ -4187,8 +4191,12 @@ package android.media {
method public void onAudioServerUp();
}
- public static interface AudioManager.OnPreferredDeviceForStrategyChangedListener {
- method public void onPreferredDeviceForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @Nullable android.media.AudioDeviceAttributes);
+ @Deprecated public static interface AudioManager.OnPreferredDeviceForStrategyChangedListener {
+ method @Deprecated public void onPreferredDeviceForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @Nullable android.media.AudioDeviceAttributes);
+ }
+
+ public static interface AudioManager.OnPreferredDevicesForStrategyChangedListener {
+ method public void onPreferredDevicesForStrategyChanged(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull java.util.List<android.media.AudioDeviceAttributes>);
}
public abstract static class AudioManager.VolumeGroupCallback {
diff --git a/packages/CarSystemUI/proguard.flags b/packages/CarSystemUI/proguard.flags
index 66cbf2650429..516e70f56158 100644
--- a/packages/CarSystemUI/proguard.flags
+++ b/packages/CarSystemUI/proguard.flags
@@ -1,4 +1,6 @@
-keep class com.android.systemui.CarSystemUIFactory
-keep class com.android.car.notification.headsup.animationhelper.**
+-keep class com.android.systemui.CarGlobalRootComponent { *; }
+
-include ../SystemUI/proguard.flags
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarGlobalRootComponent.java
index ece3bee000f9..fde0b1a97e46 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarGlobalRootComponent.java
@@ -18,9 +18,9 @@ package com.android.systemui;
import com.android.systemui.dagger.DependencyBinder;
import com.android.systemui.dagger.DependencyProvider;
+import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SystemServicesModule;
import com.android.systemui.dagger.SystemUIModule;
-import com.android.systemui.dagger.SystemUIRootComponent;
import com.android.systemui.onehanded.dagger.OneHandedModule;
import com.android.systemui.pip.phone.dagger.PipModule;
@@ -28,6 +28,7 @@ import javax.inject.Singleton;
import dagger.Component;
+/** Car subclass for GlobalRootComponent. */
@Singleton
@Component(
modules = {
@@ -41,12 +42,15 @@ import dagger.Component;
CarSystemUIModule.class,
CarSystemUIBinder.class
})
-public interface CarSystemUIRootComponent extends SystemUIRootComponent {
+public interface CarGlobalRootComponent extends GlobalRootComponent {
/**
- * Builder for a CarSystemUIRootComponent.
+ * Builder for a CarGlobalRootComponent.
*/
@Component.Builder
- interface Builder extends SystemUIRootComponent.Builder {
- CarSystemUIRootComponent build();
+ interface Builder extends GlobalRootComponent.Builder {
+ CarGlobalRootComponent build();
}
+
+ @Override
+ CarSysUIComponent.Builder getSysUIComponent();
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java
new file mode 100644
index 000000000000..d19f368f22b6
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSysUIComponent.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 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;
+
+import com.android.systemui.dagger.SysUIComponent;
+import com.android.systemui.dagger.SysUISingleton;
+
+import dagger.Subcomponent;
+
+/**
+ * Dagger Subcomponent for Core SysUI.
+ */
+@SysUISingleton
+@Subcomponent(modules = {})
+public interface CarSysUIComponent extends SysUIComponent {
+
+ /**
+ * Builder for a CarSysUIComponent.
+ */
+ @Subcomponent.Builder
+ interface Builder extends SysUIComponent.Builder {
+ CarSysUIComponent build();
+ }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
index 03ea9418415d..a65edc5477df 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
@@ -19,7 +19,7 @@ package com.android.systemui;
import android.content.Context;
import android.content.res.Resources;
-import com.android.systemui.dagger.SystemUIRootComponent;
+import com.android.systemui.dagger.GlobalRootComponent;
import java.util.HashSet;
import java.util.Set;
@@ -30,8 +30,8 @@ import java.util.Set;
public class CarSystemUIFactory extends SystemUIFactory {
@Override
- protected SystemUIRootComponent buildSystemUIRootComponent(Context context) {
- return DaggerCarSystemUIRootComponent.builder()
+ protected GlobalRootComponent buildGlobalRootComponent(Context context) {
+ return DaggerCarGlobalRootComponent.builder()
.context(context)
.build();
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index f4e704ea373e..2a96e0925428 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -32,9 +32,10 @@ import com.android.systemui.car.keyguard.CarKeyguardViewController;
import com.android.systemui.car.statusbar.DozeServiceHost;
import com.android.systemui.car.statusbar.DummyNotificationShadeWindowController;
import com.android.systemui.car.volume.CarVolumeDialogComponent;
-import com.android.systemui.dagger.SystemUIRootComponent;
+import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
import com.android.systemui.doze.DozeHost;
@@ -79,8 +80,15 @@ import dagger.Binds;
import dagger.Module;
import dagger.Provides;
-@Module(includes = {DividerModule.class, QSModule.class})
-public abstract class CarSystemUIModule {
+@Module(
+ includes = {
+ DividerModule.class,
+ QSModule.class
+ },
+ subcomponents = {
+ CarSysUIComponent.class
+ })
+abstract class CarSystemUIModule {
@Singleton
@Provides
@@ -165,10 +173,11 @@ public abstract class CarSystemUIModule {
@Singleton
static BatteryController provideBatteryController(Context context,
EnhancedEstimates enhancedEstimates, PowerManager powerManager,
- BroadcastDispatcher broadcastDispatcher, @Main Handler mainHandler,
+ BroadcastDispatcher broadcastDispatcher, DemoModeController demoModeController,
+ @Main Handler mainHandler,
@Background Handler bgHandler) {
BatteryController bC = new BatteryControllerImpl(context, enhancedEstimates, powerManager,
- broadcastDispatcher, mainHandler, bgHandler);
+ broadcastDispatcher, demoModeController, mainHandler, bgHandler);
bC.init();
return bC;
}
@@ -188,8 +197,8 @@ public abstract class CarSystemUIModule {
abstract ShadeController provideShadeController(ShadeControllerImpl shadeController);
@Binds
- abstract SystemUIRootComponent bindSystemUIRootComponent(
- CarSystemUIRootComponent systemUIRootComponent);
+ abstract GlobalRootComponent bindGlobalRootComponent(
+ CarGlobalRootComponent globalRootComponent);
@Binds
abstract VolumeDialogComponent bindVolumeDialogComponent(
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
index 98d24b1fc0e4..d45395744e91 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
@@ -19,6 +19,7 @@ package com.android.systemui.car.volume;
import android.content.Context;
import com.android.systemui.car.CarServiceProvider;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.VolumeDialog;
import com.android.systemui.volume.VolumeDialogComponent;
@@ -38,8 +39,9 @@ public class CarVolumeDialogComponent extends VolumeDialogComponent {
@Inject
public CarVolumeDialogComponent(Context context, KeyguardViewMediator keyguardViewMediator,
VolumeDialogControllerImpl volumeDialogController,
+ DemoModeController demoModeController,
CarServiceProvider carServiceProvider) {
- super(context, keyguardViewMediator, volumeDialogController);
+ super(context, keyguardViewMediator, volumeDialogController, demoModeController);
mCarVolumeDialog.setCarServiceProvider(carServiceProvider);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 4b4861a01898..59d8acb82196 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -298,18 +298,12 @@ public class BluetoothEventManager {
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
if (cachedDevice == null) {
cachedDevice = mDeviceManager.addDevice(device);
- Log.d(TAG, "DeviceFoundHandler created new CachedBluetoothDevice: "
- + cachedDevice);
+ Log.d(TAG, "DeviceFoundHandler created new CachedBluetoothDevice");
} else if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED
&& !cachedDevice.getDevice().isConnected()) {
// Dispatch device add callback to show bonded but
// not connected devices in discovery mode
dispatchDeviceAdded(cachedDevice);
- Log.d(TAG, "DeviceFoundHandler found bonded and not connected device:"
- + cachedDevice);
- } else {
- Log.d(TAG, "DeviceFoundHandler found existing CachedBluetoothDevice:"
- + cachedDevice);
}
cachedDevice.setRssi(rssi);
cachedDevice.setJustDiscovered(true);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 287f80472478..4c80b91f300d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -151,8 +151,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
void onProfileStateChanged(LocalBluetoothProfile profile, int newProfileState) {
if (BluetoothUtils.D) {
- Log.d(TAG, "onProfileStateChanged: profile " + profile + ", device=" + mDevice
- + ", newProfileState " + newProfileState);
+ Log.d(TAG, "onProfileStateChanged: profile " + profile + ", device "
+ + mDevice.getAlias() + ", newProfileState " + newProfileState);
}
if (mLocalAdapter.getState() == BluetoothAdapter.STATE_TURNING_OFF)
{
@@ -290,9 +290,6 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
public void setHiSyncId(long id) {
- if (BluetoothUtils.D) {
- Log.d(TAG, "setHiSyncId: mDevice " + mDevice + ", id " + id);
- }
mHiSyncId = id;
}
@@ -638,7 +635,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
if (BluetoothUtils.D) {
- Log.e(TAG, "updating profiles for " + mDevice.getAlias() + ", " + mDevice);
+ Log.d(TAG, "updating profiles for " + mDevice.getAlias());
BluetoothClass bluetoothClass = mDevice.getBluetoothClass();
if (bluetoothClass != null) Log.v(TAG, "Class: " + bluetoothClass.toString());
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 4eea8ad92e61..f1a3fee0ea9f 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -165,6 +165,7 @@ public class SecureSettings {
Settings.Secure.AWARE_TAP_PAUSE_TOUCH_COUNT,
Settings.Secure.PEOPLE_STRIP,
Settings.Secure.MEDIA_CONTROLS_RESUME,
+ Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index c68ddbdcb5ad..04916e2c0e2b 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -244,6 +244,8 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.TAP_GESTURE, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.PEOPLE_STRIP, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.MEDIA_CONTROLS_RESUME, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.MEDIA_CONTROLS_RESUME_BLOCKED,
+ COLON_SEPARATED_PACKAGE_LIST_VALIDATOR);
VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
new InclusiveIntegerRangeValidator(
Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
index d2112a0ce759..883f4de1149c 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowPlugin.java
@@ -75,11 +75,6 @@ public interface NotificationMenuRowPlugin extends Plugin {
public MenuItem getLongpressMenuItem(Context context);
/**
- * @return the {@link MenuItem} to display when app ops icons are pressed.
- */
- public MenuItem getAppOpsMenuItem(Context context);
-
- /**
* @return the {@link MenuItem} to display when feedback icon is pressed.
*/
public MenuItem getFeedbackMenuItem(Context context);
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 14097b12e730..92e7d88868da 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -1,9 +1,9 @@
--keep class com.android.systemui.statusbar.policy.KeyButtonView {
+-keep class com.android.systemui.navigationbar.buttons.KeyButtonView {
public float getDrawingAlpha();
public void setDrawingAlpha(float);
}
--keep class com.android.systemui.statusbar.policy.KeyButtonRipple {
+-keep class com.android.systemui.navigationbar.buttons.KeyButtonRipple {
public float getGlowAlpha();
public float getGlowScale();
public void setGlowAlpha(float);
@@ -41,4 +41,6 @@
public <init>(android.content.Context);
}
--keep class com.android.wm.shell.* \ No newline at end of file
+-keep class com.android.wm.shell.*
+
+-keep class com.android.systemui.dagger.GlobalRootComponent { *; } \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml
index 4e8726b3a634..046aecda44b3 100644
--- a/packages/SystemUI/res/layout/back.xml
+++ b/packages/SystemUI/res/layout/back.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.systemui.statusbar.policy.KeyButtonView
+<com.android.systemui.navigationbar.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/back"
diff --git a/packages/SystemUI/res/layout/contextual.xml b/packages/SystemUI/res/layout/contextual.xml
index 90a776884699..2cd7926b6e46 100644
--- a/packages/SystemUI/res/layout/contextual.xml
+++ b/packages/SystemUI/res/layout/contextual.xml
@@ -24,7 +24,7 @@
android:clipChildren="false"
android:clipToPadding="false"
>
- <com.android.systemui.statusbar.policy.KeyButtonView
+ <com.android.systemui.navigationbar.buttons.KeyButtonView
android:id="@+id/menu"
android:layout_height="match_parent"
android:layout_width="match_parent"
@@ -47,7 +47,7 @@
android:layout_height="match_parent"
android:visibility="invisible"
/>
- <com.android.systemui.statusbar.policy.KeyButtonView
+ <com.android.systemui.navigationbar.buttons.KeyButtonView
android:id="@+id/accessibility_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/custom_key.xml b/packages/SystemUI/res/layout/custom_key.xml
index 0b5cb7267610..dc65777542e2 100644
--- a/packages/SystemUI/res/layout/custom_key.xml
+++ b/packages/SystemUI/res/layout/custom_key.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.systemui.statusbar.policy.KeyButtonView
+<com.android.systemui.navigationbar.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/navigation_side_padding"
diff --git a/packages/SystemUI/res/layout/home.xml b/packages/SystemUI/res/layout/home.xml
index 95863272b9bf..84eed6a233f8 100644
--- a/packages/SystemUI/res/layout/home.xml
+++ b/packages/SystemUI/res/layout/home.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.systemui.statusbar.policy.KeyButtonView
+<com.android.systemui.navigationbar.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/home"
diff --git a/packages/SystemUI/res/layout/home_handle.xml b/packages/SystemUI/res/layout/home_handle.xml
index 54a0b9fba39c..c9d3f987902c 100644
--- a/packages/SystemUI/res/layout/home_handle.xml
+++ b/packages/SystemUI/res/layout/home_handle.xml
@@ -15,7 +15,7 @@
~ limitations under the License.
-->
-<com.android.systemui.statusbar.phone.NavigationHandle
+<com.android.systemui.navigationbar.gestural.NavigationHandle
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/home_handle"
android:layout_width="@dimen/navigation_home_handle_width"
diff --git a/packages/SystemUI/res/layout/ime_switcher.xml b/packages/SystemUI/res/layout/ime_switcher.xml
index 7710b25d6e4c..a2c8308b7f70 100644
--- a/packages/SystemUI/res/layout/ime_switcher.xml
+++ b/packages/SystemUI/res/layout/ime_switcher.xml
@@ -15,7 +15,7 @@
~ limitations under the License
-->
-<com.android.systemui.statusbar.policy.KeyButtonView
+<com.android.systemui.navigationbar.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ime_switcher"
android:layout_width="@dimen/navigation_key_width"
diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml
index df717f601763..0bb622bb9c4f 100644
--- a/packages/SystemUI/res/layout/menu_ime.xml
+++ b/packages/SystemUI/res/layout/menu_ime.xml
@@ -25,7 +25,7 @@
are placed inside a view that has a size controlled by weight. Ensure weight is large enough to
support icon size. Use layout_width=navigation_side_padding like other navbar buttons. -->
- <com.android.systemui.statusbar.policy.KeyButtonView
+ <com.android.systemui.navigationbar.buttons.KeyButtonView
android:id="@+id/menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -43,7 +43,7 @@
android:paddingStart="0dp"
android:paddingEnd="0dp"
/>
- <com.android.systemui.statusbar.policy.KeyButtonView
+ <com.android.systemui.navigationbar.buttons.KeyButtonView
android:id="@+id/rotate_suggestion"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -51,7 +51,7 @@
android:scaleType="centerInside"
android:contentDescription="@string/accessibility_rotate_button"
/>
- <com.android.systemui.statusbar.policy.KeyButtonView
+ <com.android.systemui.navigationbar.buttons.KeyButtonView
android:id="@+id/accessibility_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index ba6b6956f187..23f36a98ed3e 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -17,9 +17,10 @@
*/
-->
-<com.android.systemui.statusbar.phone.NavigationBarView
+<com.android.systemui.navigationbar.NavigationBarView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/navigation_bar_view"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@drawable/system_bar_background">
@@ -39,9 +40,9 @@
android:rotation="180"
android:visibility="gone"/>
- <com.android.systemui.statusbar.phone.NavigationBarInflaterView
+ <com.android.systemui.navigationbar.NavigationBarInflaterView
android:id="@+id/navigation_inflater"
android:layout_width="match_parent"
android:layout_height="match_parent" />
-</com.android.systemui.statusbar.phone.NavigationBarView>
+</com.android.systemui.navigationbar.NavigationBarView>
diff --git a/packages/SystemUI/res/layout/navigation_bar_window.xml b/packages/SystemUI/res/layout/navigation_bar_window.xml
index f98cbd8d10fa..b2473cd82998 100644
--- a/packages/SystemUI/res/layout/navigation_bar_window.xml
+++ b/packages/SystemUI/res/layout/navigation_bar_window.xml
@@ -16,7 +16,7 @@
** limitations under the License.
*/
-->
-<com.android.systemui.statusbar.phone.NavigationBarFrame
+<com.android.systemui.navigationbar.NavigationBarFrame
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_bar_frame"
@@ -24,4 +24,4 @@
android:layout_height="match_parent"
android:layout_width="match_parent">
-</com.android.systemui.statusbar.phone.NavigationBarFrame>
+</com.android.systemui.navigationbar.NavigationBarFrame>
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index db1c79d24c54..0e576fbe2245 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -25,7 +25,7 @@
android:paddingEnd="@dimen/nav_content_padding"
android:id="@+id/horizontal">
- <com.android.systemui.statusbar.phone.NearestTouchFrame
+ <com.android.systemui.navigationbar.buttons.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -50,6 +50,6 @@
android:clipToPadding="false"
android:clipChildren="false" />
- </com.android.systemui.statusbar.phone.NearestTouchFrame>
+ </com.android.systemui.navigationbar.buttons.NearestTouchFrame>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/navigation_layout_vertical.xml b/packages/SystemUI/res/layout/navigation_layout_vertical.xml
index 285c5c4e0a01..4b6770042632 100644
--- a/packages/SystemUI/res/layout/navigation_layout_vertical.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_vertical.xml
@@ -25,14 +25,14 @@
android:paddingBottom="@dimen/nav_content_padding"
android:id="@+id/vertical">
- <com.android.systemui.statusbar.phone.NearestTouchFrame
+ <com.android.systemui.navigationbar.buttons.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
- <com.android.systemui.statusbar.phone.ReverseLinearLayout
+ <com.android.systemui.navigationbar.buttons.ReverseLinearLayout
android:id="@+id/ends_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -40,7 +40,7 @@
android:clipToPadding="false"
android:clipChildren="false" />
- <com.android.systemui.statusbar.phone.ReverseLinearLayout
+ <com.android.systemui.navigationbar.buttons.ReverseLinearLayout
android:id="@+id/center_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -49,6 +49,6 @@
android:clipToPadding="false"
android:clipChildren="false" />
- </com.android.systemui.statusbar.phone.NearestTouchFrame>
+ </com.android.systemui.navigationbar.buttons.NearestTouchFrame>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml
index 870bcf7547a7..e2b1374b6a78 100644
--- a/packages/SystemUI/res/layout/recent_apps.xml
+++ b/packages/SystemUI/res/layout/recent_apps.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<com.android.systemui.statusbar.policy.KeyButtonView
+<com.android.systemui.navigationbar.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/recent_apps"
diff --git a/packages/SystemUI/res/layout/rotate_suggestion.xml b/packages/SystemUI/res/layout/rotate_suggestion.xml
index d7f67db0390c..194d2e063e97 100644
--- a/packages/SystemUI/res/layout/rotate_suggestion.xml
+++ b/packages/SystemUI/res/layout/rotate_suggestion.xml
@@ -15,7 +15,7 @@
~ limitations under the License
-->
-<com.android.systemui.statusbar.policy.KeyButtonView
+<com.android.systemui.navigationbar.buttons.KeyButtonView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rotate_suggestion"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 17ba7c99dc0c..ce1ca5ad1723 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -565,15 +565,9 @@
<!-- If the config font scale is >= this value, potentially adjust the number of columns-->
<item name="controls_max_columns_adjust_above_font_scale" translatable="false" format="float" type="dimen">1.25</item>
- <!-- One handed mode default offset % of display size -->
- <fraction name="config_one_handed_offset">50%</fraction>
-
<!-- Allow one handed to enable round corner -->
<bool name="config_one_handed_enable_round_corner">true</bool>
- <!-- Animation duration for translating of one handed when trigger / dismiss. -->
- <integer name="config_one_handed_translate_animation_duration">150</integer>
-
<!-- Show a separate icon for low and high volume on the volume dialog -->
<bool name="config_showLowMediaVolumeIcon">false</bool>
</resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index d6fabd63420d..6f19613be28f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -36,8 +36,8 @@ import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.statusbar.NavigationBarController;
-import com.android.systemui.statusbar.phone.NavigationBarView;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.util.InjectionInflationController;
public class KeyguardDisplayManager {
@@ -54,9 +54,6 @@ public class KeyguardDisplayManager {
private final SparseArray<Presentation> mPresentations = new SparseArray<>();
- private final NavigationBarController mNavBarController =
- Dependency.get(NavigationBarController.class);
-
private final DisplayManager.DisplayListener mDisplayListener =
new DisplayManager.DisplayListener() {
@@ -227,7 +224,8 @@ public class KeyguardDisplayManager {
// Leave this task to {@link StatusBarKeyguardViewManager}
if (displayId == DEFAULT_DISPLAY) return;
- NavigationBarView navBarView = mNavBarController.getNavigationBarView(displayId);
+ NavigationBarView navBarView = Dependency.get(NavigationBarController.class)
+ .getNavigationBarView(displayId);
// We may not have nav bar on a display.
if (navBarView == null) return;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 1db2e32b8cdb..5f00a591860e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -256,7 +256,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
mUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y);
mInjectionInflationController = new InjectionInflationController(
- SystemUIFactory.getInstance().getRootComponent());
+ SystemUIFactory.getInstance().getRootComponent().createViewInstanceCreatorFactory());
mViewConfiguration = ViewConfiguration.get(context);
mKeyguardStateController = Dependency.get(KeyguardStateController.class);
mSecondaryLockScreenController = new AdminSecondaryLockScreenController(context, this,
diff --git a/packages/SystemUI/src/com/android/systemui/DemoMode.java b/packages/SystemUI/src/com/android/systemui/DemoMode.java
deleted file mode 100644
index 5c3971571b87..000000000000
--- a/packages/SystemUI/src/com/android/systemui/DemoMode.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.os.Bundle;
-
-public interface DemoMode {
-
- public static final String DEMO_MODE_ALLOWED = "sysui_demo_allowed";
-
- void dispatchDemoCommand(String command, Bundle args);
-
- public static final String ACTION_DEMO = "com.android.systemui.demo";
-
- public static final String EXTRA_COMMAND = "command";
-
- public static final String COMMAND_ENTER = "enter";
- public static final String COMMAND_EXIT = "exit";
- public static final String COMMAND_CLOCK = "clock";
- public static final String COMMAND_BATTERY = "battery";
- public static final String COMMAND_NETWORK = "network";
- public static final String COMMAND_BARS = "bars";
- public static final String COMMAND_STATUS = "status";
- public static final String COMMAND_NOTIFICATIONS = "notifications";
- public static final String COMMAND_VOLUME = "volume";
- public static final String COMMAND_OPERATOR = "operator";
-}
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 58f8c07ad7c9..10f2069087d5 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -64,7 +64,7 @@ import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
import com.android.systemui.shared.system.PackageManagerWrapper;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -85,7 +85,7 @@ import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
import com.android.systemui.statusbar.phone.ManagedProfileController;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index 2deeb1230f09..5f8815665d88 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -39,21 +39,15 @@ import javax.inject.Singleton;
*/
@Singleton
public class ForegroundServiceController {
- public static final int[] APP_OPS = new int[] {AppOpsManager.OP_CAMERA,
- AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
- AppOpsManager.OP_RECORD_AUDIO,
- AppOpsManager.OP_COARSE_LOCATION,
- AppOpsManager.OP_FINE_LOCATION};
+ public static final int[] APP_OPS = new int[] {AppOpsManager.OP_SYSTEM_ALERT_WINDOW};
private final SparseArray<ForegroundServicesUserState> mUserServices = new SparseArray<>();
private final Object mMutex = new Object();
- private final NotificationEntryManager mEntryManager;
private final Handler mMainHandler;
@Inject
- public ForegroundServiceController(NotificationEntryManager entryManager,
- AppOpsController appOpsController, @Main Handler mainHandler) {
- mEntryManager = entryManager;
+ public ForegroundServiceController(AppOpsController appOpsController,
+ @Main Handler mainHandler) {
mMainHandler = mainHandler;
appOpsController.addCallback(APP_OPS, (code, uid, packageName, active) -> {
mMainHandler.post(() -> {
@@ -87,19 +81,6 @@ public class ForegroundServiceController {
}
/**
- * Returns the keys for notifications from this package using the standard template,
- * if they exist.
- */
- @Nullable
- public ArraySet<String> getStandardLayoutKeys(int userId, String pkg) {
- synchronized (mMutex) {
- final ForegroundServicesUserState services = mUserServices.get(userId);
- if (services == null) return null;
- return services.getStandardLayoutKeys(pkg);
- }
- }
-
- /**
* Gets active app ops for this user and package
*/
@Nullable
@@ -140,31 +121,6 @@ public class ForegroundServiceController {
userServices.removeOp(packageName, appOpCode);
}
}
-
- // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
- // AppOpsCoordinator
- // Update appOps if there are associated pending or visible notifications
- final Set<String> notificationKeys = getStandardLayoutKeys(userId, packageName);
- if (notificationKeys != null) {
- boolean changed = false;
- for (String key : notificationKeys) {
- final NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(key);
- if (entry != null
- && uid == entry.getSbn().getUid()
- && packageName.equals(entry.getSbn().getPackageName())) {
- synchronized (entry.mActiveAppOps) {
- if (active) {
- changed |= entry.mActiveAppOps.add(appOpCode);
- } else {
- changed |= entry.mActiveAppOps.remove(appOpCode);
- }
- }
- }
- }
- if (changed) {
- mEntryManager.updateNotifications("appOpChanged pkg=" + packageName);
- }
- }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
index bb445832da93..1515272569d6 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java
@@ -172,24 +172,8 @@ public class ForegroundServiceNotificationListener {
sbn.getPackageName(), sbn.getKey());
}
}
- tagAppOps(entry);
return true;
},
true /* create if not found */);
}
-
- // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by
- // AppOpsCoordinator
- private void tagAppOps(NotificationEntry entry) {
- final StatusBarNotification sbn = entry.getSbn();
- ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps(
- sbn.getUserId(),
- sbn.getPackageName());
- synchronized (entry.mActiveAppOps) {
- entry.mActiveAppOps.clear();
- if (activeOps != null) {
- entry.mActiveAppOps.addAll(activeOps);
- }
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
index 449ed8c3bcdb..2365f128532e 100644
--- a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
@@ -16,6 +16,7 @@ package com.android.systemui;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+import android.annotation.Nullable;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.slice.SliceManager;
@@ -29,6 +30,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Bundle;
import android.text.BidiFormatter;
+import android.util.EventLog;
import android.util.Log;
import android.widget.CheckBox;
import android.widget.TextView;
@@ -50,10 +52,17 @@ public class SlicePermissionActivity extends Activity implements OnClickListener
mUri = getIntent().getParcelableExtra(SliceProvider.EXTRA_BIND_URI);
mCallingPkg = getIntent().getStringExtra(SliceProvider.EXTRA_PKG);
- mProviderPkg = getIntent().getStringExtra(SliceProvider.EXTRA_PROVIDER_PKG);
+ if (mUri == null) {
+ Log.e(TAG, SliceProvider.EXTRA_BIND_URI + " wasn't provided");
+ finish();
+ return;
+ }
try {
PackageManager pm = getPackageManager();
+ mProviderPkg = pm.resolveContentProvider(mUri.getAuthority(),
+ PackageManager.GET_META_DATA).applicationInfo.packageName;
+ verifyCallingPkg();
CharSequence app1 = BidiFormatter.getInstance().unicodeWrap(pm.getApplicationInfo(
mCallingPkg, 0).loadSafeLabel(pm, PackageItemInfo.DEFAULT_MAX_LABEL_SIZE_PX,
PackageItemInfo.SAFE_LABEL_FLAG_TRIM
@@ -97,4 +106,29 @@ public class SlicePermissionActivity extends Activity implements OnClickListener
public void onDismiss(DialogInterface dialog) {
finish();
}
+
+ private void verifyCallingPkg() {
+ final String providerPkg = getIntent().getStringExtra("provider_pkg");
+ if (providerPkg == null || mProviderPkg.equals(providerPkg)) return;
+ final String callingPkg = getCallingPkg();
+ EventLog.writeEvent(0x534e4554, "159145361", getUid(callingPkg), String.format(
+ "pkg %s (disguised as %s) attempted to request permission to show %s slices in %s",
+ callingPkg, providerPkg, mProviderPkg, mCallingPkg));
+ }
+
+ @Nullable
+ private String getCallingPkg() {
+ final Uri referrer = getReferrer();
+ if (referrer == null) return null;
+ return referrer.getHost();
+ }
+
+ private int getUid(@Nullable final String pkg) {
+ if (pkg == null) return -1;
+ try {
+ return getPackageManager().getApplicationInfo(pkg, 0).uid;
+ } catch (NameNotFoundException e) {
+ }
+ return -1;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
index cacbf969e562..627f5592e667 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
@@ -29,6 +29,10 @@ import androidx.annotation.Nullable;
import androidx.core.app.AppComponentFactory;
import com.android.systemui.dagger.ContextComponentHelper;
+import com.android.systemui.dagger.GlobalRootComponent;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import javax.inject.Inject;
@@ -81,8 +85,17 @@ public class SystemUIAppComponentFactory extends AppComponentFactory {
((ContextInitializer) contentProvider).setContextAvailableCallback(
context -> {
SystemUIFactory.createFromConfig(context);
- SystemUIFactory.getInstance().getRootComponent().inject(
- contentProvider);
+ GlobalRootComponent rootComponent =
+ SystemUIFactory.getInstance().getRootComponent();
+ try {
+ Method injectMethod = rootComponent.getClass()
+ .getMethod("inject", contentProvider.getClass());
+ injectMethod.invoke(rootComponent, contentProvider);
+ } catch (NoSuchMethodException
+ | IllegalAccessException
+ | InvocationTargetException e) {
+ // no-op
+ }
}
);
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index c84701c9512e..4f78f65f0121 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -32,7 +32,7 @@ import android.util.Log;
import android.util.TimingsTraceLog;
import com.android.systemui.dagger.ContextComponentHelper;
-import com.android.systemui.dagger.SystemUIRootComponent;
+import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.NotificationChannels;
@@ -57,7 +57,7 @@ public class SystemUIApplication extends Application implements
private SystemUI[] mServices;
private boolean mServicesStarted;
private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
- private SystemUIRootComponent mRootComponent;
+ private GlobalRootComponent mRootComponent;
public SystemUIApplication() {
super();
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 1a15c0aae8c1..e34a653f4d2f 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -28,8 +28,11 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.bubbles.BubbleController;
-import com.android.systemui.dagger.DaggerSystemUIRootComponent;
-import com.android.systemui.dagger.SystemUIRootComponent;
+import com.android.systemui.dagger.DaggerGlobalRootComponent;
+import com.android.systemui.dagger.GlobalRootComponent;
+import com.android.systemui.dagger.SysUIComponent;
+import com.android.systemui.dagger.WMComponent;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -53,7 +56,9 @@ public class SystemUIFactory {
private static final String TAG = "SystemUIFactory";
static SystemUIFactory mFactory;
- private SystemUIRootComponent mRootComponent;
+ private GlobalRootComponent mRootComponent;
+ private WMComponent mWMComponent;
+ private SysUIComponent mSysUIComponent;
public static <T extends SystemUIFactory> T getInstance() {
return (T) mFactory;
@@ -88,7 +93,10 @@ public class SystemUIFactory {
public SystemUIFactory() {}
private void init(Context context) {
- mRootComponent = buildSystemUIRootComponent(context);
+ mRootComponent = buildGlobalRootComponent(context);
+ mWMComponent = mRootComponent.getWMComponentBuilder().build();
+ // TODO: use WMComponent to pass APIs into the SysUIComponent.
+ mSysUIComponent = mRootComponent.getSysUIComponent().build();
// Every other part of our codebase currently relies on Dependency, so we
// really need to ensure the Dependency gets initialized early on.
@@ -96,13 +104,13 @@ public class SystemUIFactory {
dependency.start();
}
- protected SystemUIRootComponent buildSystemUIRootComponent(Context context) {
- return DaggerSystemUIRootComponent.builder()
+ protected GlobalRootComponent buildGlobalRootComponent(Context context) {
+ return DaggerGlobalRootComponent.builder()
.context(context)
.build();
}
- public SystemUIRootComponent getRootComponent() {
+ public GlobalRootComponent getRootComponent() {
return mRootComponent;
}
@@ -144,12 +152,14 @@ public class SystemUIFactory {
StatusBar statusBar,
NotificationWakeUpCoordinator wakeUpCoordinator,
KeyguardBypassController keyguardBypassController,
- StatusBarStateController statusBarStateController) {
+ StatusBarStateController statusBarStateController,
+ DemoModeController demoModeController) {
return new NotificationIconAreaController(context, statusBar, statusBarStateController,
wakeUpCoordinator, keyguardBypassController,
Dependency.get(NotificationMediaManager.class),
Dependency.get(NotificationListener.class),
Dependency.get(DozeParameters.class),
- Dependency.get(BubbleController.class));
+ Dependency.get(BubbleController.class),
+ demoModeController);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index 0135e4cddc56..17525798ae08 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -130,8 +130,6 @@ public class SystemActions extends SystemUI {
private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
- private Recents mRecents;
- private StatusBar mStatusBar;
private SystemActionsBroadcastReceiver mReceiver;
private Locale mLocale;
private AccessibilityManager mA11yManager;
@@ -139,8 +137,6 @@ public class SystemActions extends SystemUI {
@Inject
public SystemActions(Context context) {
super(context);
- mRecents = Dependency.get(Recents.class);
- mStatusBar = Dependency.get(StatusBar.class);
mReceiver = new SystemActionsBroadcastReceiver();
mLocale = mContext.getResources().getConfiguration().getLocales().get(0);
mA11yManager = (AccessibilityManager) mContext.getSystemService(
@@ -317,15 +313,15 @@ public class SystemActions extends SystemUI {
}
private void handleRecents() {
- mRecents.toggleRecentApps();
+ Dependency.get(Recents.class).toggleRecentApps();
}
private void handleNotifications() {
- mStatusBar.animateExpandNotificationsPanel();
+ Dependency.get(StatusBar.class).animateExpandNotificationsPanel();
}
private void handleQuickSettings() {
- mStatusBar.animateExpandSettingsPanel(null);
+ Dependency.get(StatusBar.class).animateExpandSettingsPanel(null);
}
private void handlePowerDialog() {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
index 7ae3e73caa23..2df48fc90a94 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
@@ -35,7 +35,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dumpable;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleViewController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleViewController.java
index 5010f319f8b4..f19e53f03849 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleViewController.java
@@ -30,7 +30,7 @@ import android.view.animation.PathInterpolator;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.CornerHandleView;
import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.NavigationBarTransitions;
+import com.android.systemui.navigationbar.NavigationBarTransitions;
/**
* A class for managing Assistant handle show, hide and animation.
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java b/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java
index 6f5a17dca432..0dc06f2d5e21 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistModule.java
@@ -25,7 +25,7 @@ import androidx.annotation.Nullable;
import androidx.slice.Clock;
import com.android.internal.app.AssistUtils;
-import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationBarController;
import java.util.EnumMap;
import java.util.Map;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
index 05f3617dd1d6..722e3124d871 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
@@ -41,7 +41,7 @@ import com.android.systemui.assist.AssistHandleViewController;
import com.android.systemui.assist.AssistLogger;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.assist.AssistantSessionEvent;
-import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationBarController;
import java.util.Locale;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
index e5121a8ea35c..ac39ed501811 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
@@ -33,9 +33,9 @@ import android.view.View;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.statusbar.NavigationBarController;
-import com.android.systemui.statusbar.phone.NavigationBarFragment;
-import com.android.systemui.statusbar.phone.NavigationBarTransitions;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationBar;
+import com.android.systemui.navigationbar.NavigationBarTransitions;
import java.util.ArrayList;
@@ -284,7 +284,7 @@ public class InvocationLightsView extends View
return;
}
- NavigationBarFragment navBar = controller.getDefaultNavigationBarFragment();
+ NavigationBar navBar = controller.getDefaultNavigationBar();
if (navBar == null) {
return;
}
@@ -301,7 +301,7 @@ public class InvocationLightsView extends View
return;
}
- NavigationBarFragment navBar = controller.getDefaultNavigationBarFragment();
+ NavigationBar navBar = controller.getDefaultNavigationBar();
if (navBar == null) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 361ea674cead..ade106fb2223 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -280,7 +280,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
fpm.getSensorProperties();
for (FingerprintSensorProperties props : fingerprintSensorProperties) {
if (props.sensorType == FingerprintSensorProperties.TYPE_UDFPS) {
- mUdfpsController = new UdfpsController(mContext, mWindowManager);
+ mUdfpsController = new UdfpsController(mContext);
break;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 739c2b155444..e3126b89fe78 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -17,21 +17,27 @@
package com.android.systemui.biometrics;
import android.annotation.SuppressLint;
+import android.content.ContentResolver;
import android.content.Context;
+import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.IFingerprintService;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.Handler;
import android.os.Looper;
-import android.os.RemoteException;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.util.Log;
+import android.util.MathUtils;
+import android.util.Spline;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.LinearLayout;
+import com.android.internal.BrightnessSynchronizer;
import com.android.systemui.R;
import java.io.FileWriter;
@@ -43,17 +49,31 @@ import java.io.IOException;
*/
class UdfpsController {
private static final String TAG = "UdfpsController";
+ // Gamma approximation for the sRGB color space.
+ private static final float DISPLAY_GAMMA = 2.2f;
- private final Context mContext;
private final FingerprintManager mFingerprintManager;
private final WindowManager mWindowManager;
+ private final ContentResolver mContentResolver;
private final Handler mHandler;
-
- private UdfpsView mView;
- private WindowManager.LayoutParams mLayoutParams;
- private String mHbmPath;
- private String mHbmEnableCommand;
- private String mHbmDisableCommand;
+ private final UdfpsView mView;
+ private final WindowManager.LayoutParams mLayoutParams;
+ // Debugfs path to control the high-brightness mode.
+ private final String mHbmPath;
+ private final String mHbmEnableCommand;
+ private final String mHbmDisableCommand;
+ // Brightness in nits in the high-brightness mode.
+ private final float mHbmNits;
+ // A spline mapping from the device's backlight value, normalized to the range [0, 1.0], to a
+ // brightness in nits.
+ private final Spline mBacklightToNitsSpline;
+ // A spline mapping from a value in nits to a backlight value of a hypothetical panel whose
+ // maximum backlight value corresponds to our panel's high-brightness mode.
+ // The output is normalized to the range [0, 1.0].
+ private Spline mNitsToHbmBacklightSpline;
+ // Default non-HBM backlight value normalized to the range [0, 1.0]. Used as a fallback when the
+ // actual brightness value cannot be retrieved.
+ private final float mDefaultBrightness;
private boolean mIsOverlayShowing;
public class UdfpsOverlayController extends IUdfpsOverlayController.Stub {
@@ -70,22 +90,23 @@ class UdfpsController {
@SuppressLint("ClickableViewAccessibility")
private final UdfpsView.OnTouchListener mOnTouchListener = (v, event) -> {
+ UdfpsView view = (UdfpsView) v;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
- boolean isValidTouch = mView.isValidTouch(event.getX(), event.getY(),
+ boolean isValidTouch = view.isValidTouch(event.getX(), event.getY(),
event.getPressure());
- if (!mView.isFingerDown() && isValidTouch) {
+ if (!view.isFingerDown() && isValidTouch) {
onFingerDown((int) event.getX(), (int) event.getY(), event.getTouchMinor(),
event.getTouchMajor());
- } else if (mView.isFingerDown() && !isValidTouch) {
+ } else if (view.isFingerDown() && !isValidTouch) {
onFingerUp();
}
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- if (mView.isFingerDown()) {
+ if (view.isFingerDown()) {
onFingerUp();
}
return true;
@@ -95,43 +116,51 @@ class UdfpsController {
}
};
- UdfpsController(Context context, WindowManager windowManager) {
- mContext = context;
+ UdfpsController(Context context) {
mFingerprintManager = context.getSystemService(FingerprintManager.class);
- mWindowManager = windowManager;
+ mWindowManager = context.getSystemService(WindowManager.class);
+ mContentResolver = context.getContentResolver();
mHandler = new Handler(Looper.getMainLooper());
- start();
- }
-
- private void start() {
- Log.v(TAG, "start");
-
- Point displaySize = new Point();
- mWindowManager.getDefaultDisplay().getRealSize(displaySize);
- // TODO(b/160025856): move to the "dump" method.
- Log.v(TAG, "UdfpsController | display size: " + displaySize.x + "x"
- + displaySize.y);
-
- mLayoutParams = new WindowManager.LayoutParams(
- displaySize.x,
- displaySize.y,
- // TODO(b/152419866): Use the UDFPS window type when it becomes available.
- WindowManager.LayoutParams.TYPE_BOOT_PROGRESS,
- WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
- PixelFormat.TRANSLUCENT);
- mLayoutParams.setTitle(TAG);
- mLayoutParams.windowAnimations = 0;
- LinearLayout layout = new LinearLayout(mContext);
+ mLayoutParams = createLayoutParams(context);
+ LinearLayout layout = new LinearLayout(context);
layout.setLayoutParams(mLayoutParams);
- mView = (UdfpsView) LayoutInflater.from(mContext).inflate(R.layout.udfps_view, layout,
+ mView = (UdfpsView) LayoutInflater.from(context).inflate(R.layout.udfps_view, layout,
false);
mView.setOnTouchListener(mOnTouchListener);
- mHbmPath = mContext.getResources().getString(R.string.udfps_hbm_sysfs_path);
- mHbmEnableCommand = mContext.getResources().getString(R.string.udfps_hbm_enable_command);
- mHbmDisableCommand = mContext.getResources().getString(R.string.udfps_hbm_disable_command);
+ mHbmPath = context.getResources().getString(R.string.udfps_hbm_sysfs_path);
+ mHbmEnableCommand = context.getResources().getString(R.string.udfps_hbm_enable_command);
+ mHbmDisableCommand = context.getResources().getString(R.string.udfps_hbm_disable_command);
+
+ // This range only consists of the minimum and maximum values, which only cover
+ // non-high-brightness mode.
+ float[] nitsRange = toFloatArray(context.getResources().obtainTypedArray(
+ com.android.internal.R.array.config_screenBrightnessNits));
+
+ // The last value of this range corresponds to the high-brightness mode.
+ float[] nitsAutoBrightnessValues = toFloatArray(context.getResources().obtainTypedArray(
+ com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
+
+ mHbmNits = nitsAutoBrightnessValues[nitsAutoBrightnessValues.length - 1];
+ float[] hbmNitsRange = {nitsRange[0], mHbmNits};
+
+ // This range only consists of the minimum and maximum backlight values, which only apply
+ // in non-high-brightness mode.
+ float[] normalizedBacklightRange = normalizeBacklightRange(
+ context.getResources().getIntArray(
+ com.android.internal.R.array.config_screenBrightnessBacklight));
+
+ mBacklightToNitsSpline = Spline.createSpline(normalizedBacklightRange, nitsRange);
+ mNitsToHbmBacklightSpline = Spline.createSpline(hbmNitsRange, normalizedBacklightRange);
+ mDefaultBrightness = obtainDefaultBrightness(context);
+
+ // TODO(b/160025856): move to the "dump" method.
+ Log.v(TAG, String.format("ctor | mNitsRange: [%f, %f]", nitsRange[0], nitsRange[1]));
+ Log.v(TAG, String.format("ctor | mHbmNitsRange: [%f, %f]", hbmNitsRange[0],
+ hbmNitsRange[1]));
+ Log.v(TAG, String.format("ctor | mNormalizedBacklightRange: [%f, %f]",
+ normalizedBacklightRange[0], normalizedBacklightRange[1]));
mFingerprintManager.setUdfpsOverlayController(new UdfpsOverlayController());
mIsOverlayShowing = false;
@@ -162,7 +191,34 @@ class UdfpsController {
});
}
+ // Returns a value in the range of [0, 255].
+ private int computeScrimOpacity() {
+ // Backlight setting can be NaN, -1.0f, and [0.0f, 1.0f].
+ float backlightSetting = Settings.System.getFloatForUser(mContentResolver,
+ Settings.System.SCREEN_BRIGHTNESS_FLOAT, mDefaultBrightness,
+ UserHandle.USER_CURRENT);
+
+ // Constrain the backlight setting to [0.0f, 1.0f].
+ float backlightValue = MathUtils.constrain(backlightSetting,
+ PowerManager.BRIGHTNESS_MIN,
+ PowerManager.BRIGHTNESS_MAX);
+
+ // Interpolate the backlight value to nits.
+ float nits = mBacklightToNitsSpline.interpolate(backlightValue);
+
+ // Interpolate nits to a backlight value for a panel with enabled HBM.
+ float interpolatedHbmBacklightValue = mNitsToHbmBacklightSpline.interpolate(nits);
+
+ float gammaCorrectedHbmBacklightValue = (float) Math.pow(interpolatedHbmBacklightValue,
+ 1.0f / DISPLAY_GAMMA);
+ float scrimOpacity = PowerManager.BRIGHTNESS_MAX - gammaCorrectedHbmBacklightValue;
+
+ // Interpolate the opacity value from [0.0f, 1.0f] to [0, 255].
+ return BrightnessSynchronizer.brightnessFloatToInt(scrimOpacity);
+ }
+
private void onFingerDown(int x, int y, float minor, float major) {
+ mView.setScrimAlpha(computeScrimOpacity());
try {
FileWriter fw = new FileWriter(mHbmPath);
fw.write(mHbmEnableCommand);
@@ -185,4 +241,54 @@ class UdfpsController {
Log.e(TAG, "onFingerUp | failed to disable HBM: " + e.getMessage());
}
}
+
+ private static WindowManager.LayoutParams createLayoutParams(Context context) {
+ Point displaySize = new Point();
+ context.getDisplay().getRealSize(displaySize);
+ // TODO(b/160025856): move to the "dump" method.
+ Log.v(TAG, "createLayoutParams | display size: " + displaySize.x + "x"
+ + displaySize.y);
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ displaySize.x,
+ displaySize.y,
+ // TODO(b/152419866): Use the UDFPS window type when it becomes available.
+ WindowManager.LayoutParams.TYPE_BOOT_PROGRESS,
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
+ PixelFormat.TRANSLUCENT);
+ lp.setTitle(TAG);
+ lp.windowAnimations = 0;
+ return lp;
+ }
+
+ private static float obtainDefaultBrightness(Context context) {
+ PowerManager powerManager = context.getSystemService(PowerManager.class);
+ if (powerManager == null) {
+ Log.e(TAG, "PowerManager is unavailable. Can't obtain default brightness.");
+ return 0f;
+ }
+ return MathUtils.constrain(powerManager.getBrightnessConstraint(
+ PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT), PowerManager.BRIGHTNESS_MIN,
+ PowerManager.BRIGHTNESS_MAX);
+ }
+
+ private static float[] toFloatArray(TypedArray array) {
+ final int n = array.length();
+ float[] vals = new float[n];
+ for (int i = 0; i < n; i++) {
+ vals[i] = array.getFloat(i, PowerManager.BRIGHTNESS_OFF_FLOAT);
+ }
+ array.recycle();
+ return vals;
+ }
+
+ private static float[] normalizeBacklightRange(int[] backlight) {
+ final int n = backlight.length;
+ float[] normalizedBacklight = new float[n];
+ for (int i = 0; i < n; i++) {
+ normalizedBacklight[i] = BrightnessSynchronizer.brightnessIntToFloat(backlight[i]);
+ }
+ return normalizedBacklight;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
index 8190550a74fc..d4e86d5dd234 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
@@ -79,7 +79,7 @@ public class UdfpsView extends View {
mScrimRect = new Rect();
mScrimPaint = new Paint(0 /* flags */);
- mScrimPaint.setARGB(110 /* a */, 0 /* r */, 0 /* g */, 0 /* b */);
+ mScrimPaint.setColor(Color.BLACK);
mSensorRect = new RectF();
mSensorPaint = new Paint(0 /* flags */);
@@ -136,6 +136,10 @@ public class UdfpsView extends View {
&& y < (mSensorY + mSensorRadius * mSensorTouchAreaCoefficient);
}
+ void setScrimAlpha(int alpha) {
+ mScrimPaint.setAlpha(alpha);
+ }
+
boolean isFingerDown() {
return mIsFingerDown;
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index c5639ea6fcde..9c5f9fe8bcc0 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -139,7 +139,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
@IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED,
DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE,
DISMISS_USER_CHANGED, DISMISS_GROUP_CANCELLED, DISMISS_INVALID_INTENT,
- DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED})
+ DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED,
+ DISMISS_NO_BUBBLE_UP})
@Target({FIELD, LOCAL_VARIABLE, PARAMETER})
@interface DismissReason {}
@@ -156,6 +157,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
static final int DISMISS_OVERFLOW_MAX_REACHED = 11;
static final int DISMISS_SHORTCUT_REMOVED = 12;
static final int DISMISS_PACKAGE_REMOVED = 13;
+ static final int DISMISS_NO_BUBBLE_UP = 14;
private final Context mContext;
private final NotificationEntryManager mNotificationEntryManager;
@@ -1262,8 +1264,18 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
rankingMap.getRanking(key, mTmpRanking);
boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key);
if (isActiveBubble && !mTmpRanking.canBubble()) {
- mBubbleData.dismissBubbleWithKey(entry.getKey(),
- BubbleController.DISMISS_BLOCKED);
+ // If this entry is no longer allowed to bubble, dismiss with the BLOCKED reason.
+ // This means that the app or channel's ability to bubble has been revoked.
+ mBubbleData.dismissBubbleWithKey(
+ key, BubbleController.DISMISS_BLOCKED);
+ } else if (isActiveBubble
+ && !mNotificationInterruptStateProvider.shouldBubbleUp(entry)) {
+ // If this entry is allowed to bubble, but cannot currently bubble up, dismiss it.
+ // This happens when DND is enabled and configured to hide bubbles. Dismissing with
+ // the reason DISMISS_NO_BUBBLE_UP will retain the underlying notification, so that
+ // the bubble will be re-created if shouldBubbleUp returns true.
+ mBubbleData.dismissBubbleWithKey(
+ key, BubbleController.DISMISS_NO_BUBBLE_UP);
} else if (entry != null && mTmpRanking.isBubble() && !isActiveBubble) {
entry.setFlagBubble(true);
onEntryUpdated(entry);
@@ -1340,8 +1352,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
mStackView.removeBubble(bubble);
}
- // If the bubble is removed for user switching, leave the notification in place.
- if (reason == DISMISS_USER_CHANGED) {
+ // Leave the notification in place if we're dismissing due to user switching, or
+ // because DND is suppressing the bubble. In both of those cases, we need to be able
+ // to restore the bubble from the notification later.
+ if (reason == DISMISS_USER_CHANGED || reason == DISMISS_NO_BUBBLE_UP) {
continue;
}
if (reason == DISMISS_NOTIF_CANCEL) {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 3d31070905d0..21bcfcd9fdaf 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -31,6 +31,7 @@ import android.view.Choreographer;
import android.view.IWindowManager;
import android.view.LayoutInflater;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
@@ -40,6 +41,8 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.Prefs;
import com.android.systemui.accessibility.ModeSwitchesController;
+import com.android.systemui.accessibility.SystemActions;
+import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger;
import com.android.systemui.dagger.qualifiers.Background;
@@ -47,25 +50,38 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.PluginInitializerImpl;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.recents.Recents;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginManagerImpl;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
+import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DataSaverController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.util.leak.LeakDetector;
+import java.util.Optional;
import java.util.concurrent.Executor;
import javax.inject.Named;
import javax.inject.Singleton;
+import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
@@ -159,8 +175,49 @@ public class DependencyProvider {
@Singleton
@Provides
public NavigationBarController provideNavigationBarController(Context context,
- @Main Handler mainHandler, CommandQueue commandQueue) {
- return new NavigationBarController(context, mainHandler, commandQueue);
+ WindowManager windowManager,
+ Lazy<AssistManager> assistManagerLazy,
+ AccessibilityManager accessibilityManager,
+ AccessibilityManagerWrapper accessibilityManagerWrapper,
+ DeviceProvisionedController deviceProvisionedController,
+ MetricsLogger metricsLogger,
+ OverviewProxyService overviewProxyService,
+ NavigationModeController navigationModeController,
+ StatusBarStateController statusBarStateController,
+ SysUiState sysUiFlagsContainer,
+ BroadcastDispatcher broadcastDispatcher,
+ CommandQueue commandQueue,
+ Divider divider,
+ Optional<Recents> recentsOptional,
+ Lazy<StatusBar> statusBarLazy,
+ ShadeController shadeController,
+ NotificationRemoteInputManager notificationRemoteInputManager,
+ SystemActions systemActions,
+ @Main Handler mainHandler,
+ UiEventLogger uiEventLogger,
+ ConfigurationController configurationController) {
+ return new NavigationBarController(context,
+ windowManager,
+ assistManagerLazy,
+ accessibilityManager,
+ accessibilityManagerWrapper,
+ deviceProvisionedController,
+ metricsLogger,
+ overviewProxyService,
+ navigationModeController,
+ statusBarStateController,
+ sysUiFlagsContainer,
+ broadcastDispatcher,
+ commandQueue,
+ divider,
+ recentsOptional,
+ statusBarLazy,
+ shadeController,
+ notificationRemoteInputManager,
+ systemActions,
+ mainHandler,
+ uiEventLogger,
+ configurationController);
}
@Singleton
@@ -230,6 +287,12 @@ public class DependencyProvider {
}
/** */
+ @Provides
+ public SystemActions providesSystemActions(Context context) {
+ return new SystemActions(context);
+ }
+
+ /** */
@Singleton
@Provides
public Choreographer providesChoreographer() {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
index 9fdbb6daca51..9c55095e85e5 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/GlobalRootComponent.java
@@ -16,9 +16,6 @@
package com.android.systemui.dagger;
-import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
-
-import android.content.ContentProvider;
import android.content.Context;
import com.android.systemui.BootCompleteCacheImpl;
@@ -26,14 +23,12 @@ import com.android.systemui.Dependency;
import com.android.systemui.InitController;
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.dump.DumpManager;
-import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.onehanded.dagger.OneHandedModule;
import com.android.systemui.pip.phone.dagger.PipModule;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.InjectionInflationController;
-import javax.inject.Named;
import javax.inject.Singleton;
import dagger.BindsInstance;
@@ -42,6 +37,7 @@ import dagger.Component;
/**
* Root component for Dagger injection.
*/
+// TODO(b/162923491): Move most of these modules to SysUIComponent.
@Singleton
@Component(modules = {
DefaultComponentBinder.class,
@@ -52,21 +48,32 @@ import dagger.Component;
SystemServicesModule.class,
SystemUIBinder.class,
SystemUIModule.class,
- SystemUIDefaultModule.class})
-public interface SystemUIRootComponent {
+ SystemUIDefaultModule.class,
+ WMModule.class})
+public interface GlobalRootComponent {
/**
- * Builder for a SystemUIRootComponent.
+ * Builder for a GlobalRootComponent.
*/
@Component.Builder
interface Builder {
@BindsInstance
Builder context(Context context);
- SystemUIRootComponent build();
+ GlobalRootComponent build();
}
/**
+ * Builder for a WMComponent.
+ */
+ WMComponent.Builder getWMComponentBuilder();
+
+ /**
+ * Builder for a SysuiComponent.
+ */
+ SysUIComponent.Builder getSysUIComponent();
+
+ /**
* Provides a BootCompleteCache.
*/
@Singleton
@@ -95,28 +102,15 @@ public interface SystemUIRootComponent {
DumpManager createDumpManager();
/**
- * FragmentCreator generates all Fragments that need injection.
- */
- @Singleton
- FragmentService.FragmentCreator createFragmentCreator();
-
-
- /**
* Creates a InitController.
*/
@Singleton
InitController getInitController();
/**
- * ViewCreator generates all Views that need injection.
- */
- InjectionInflationController.ViewCreator createViewCreator();
-
- /**
- * Whether notification long press is allowed.
+ * ViewInstanceCreator generates all Views that need injection.
*/
- @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
- boolean allowNotificationLongPressName();
+ InjectionInflationController.ViewInstanceCreator.Factory createViewInstanceCreatorFactory();
/**
* Member injection into the supplied argument.
@@ -126,10 +120,5 @@ public interface SystemUIRootComponent {
/**
* Member injection into the supplied argument.
*/
- void inject(ContentProvider contentProvider);
-
- /**
- * Member injection into the supplied argument.
- */
void inject(KeyguardSliceProvider keyguardSliceProvider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
new file mode 100644
index 000000000000..9b527bfeda27
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 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.dagger;
+
+import dagger.Subcomponent;
+
+/**
+ * Dagger Subcomponent for Core SysUI.
+ */
+@SysUISingleton
+@Subcomponent(modules = {})
+public interface SysUIComponent {
+
+ /**
+ * Builder for a SysUIComponent.
+ */
+ @Subcomponent.Builder
+ interface Builder {
+ SysUIComponent build();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUISingleton.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUISingleton.java
new file mode 100644
index 000000000000..a4b33427cbda
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUISingleton.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Scope;
+
+/**
+ * Scope annotation for singleton items within the SysUIComponent.
+ */
+@Documented
+@Retention(RUNTIME)
+@Scope
+public @interface SysUISingleton {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 803e56db8ff3..56219c3356fc 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -29,6 +29,7 @@ import com.android.keyguard.KeyguardViewController;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
import com.android.systemui.doze.DozeHost;
@@ -72,7 +73,14 @@ import dagger.Provides;
* A dagger module for injecting default implementations of components of System UI that may be
* overridden by the System UI implementation.
*/
-@Module(includes = {DividerModule.class, QSModule.class, WindowManagerShellModule.class})
+@Module(includes = {
+ DividerModule.class,
+ QSModule.class,
+ WindowManagerShellModule.class
+ },
+ subcomponents = {
+ SysUIComponent.class
+ })
public abstract class SystemUIDefaultModule {
@Singleton
@@ -92,12 +100,22 @@ public abstract class SystemUIDefaultModule {
@Provides
@Singleton
- static BatteryController provideBatteryController(Context context,
- EnhancedEstimates enhancedEstimates, PowerManager powerManager,
- BroadcastDispatcher broadcastDispatcher, @Main Handler mainHandler,
+ static BatteryController provideBatteryController(
+ Context context,
+ EnhancedEstimates enhancedEstimates,
+ PowerManager powerManager,
+ BroadcastDispatcher broadcastDispatcher,
+ DemoModeController demoModeController,
+ @Main Handler mainHandler,
@Background Handler bgHandler) {
- BatteryController bC = new BatteryControllerImpl(context, enhancedEstimates, powerManager,
- broadcastDispatcher, mainHandler, bgHandler);
+ BatteryController bC = new BatteryControllerImpl(
+ context,
+ enhancedEstimates,
+ powerManager,
+ broadcastDispatcher,
+ demoModeController,
+ mainHandler,
+ bgHandler);
bC.init();
return bC;
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index f774358b69fb..a46e182327f8 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -24,8 +24,10 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.BootCompleteCacheImpl;
import com.android.systemui.assist.AssistModule;
+import com.android.systemui.demomode.dagger.DemoModeModule;
import com.android.systemui.doze.dagger.DozeComponent;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.fragments.FragmentService;
import com.android.systemui.log.dagger.LogModule;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -64,6 +66,7 @@ import dagger.Provides;
@Module(includes = {
AssistModule.class,
ConcurrencyModule.class,
+ DemoModeModule.class,
LogModule.class,
PeopleHubModule.class,
SensorModule.class,
@@ -74,7 +77,8 @@ import dagger.Provides;
NotificationRowComponent.class,
DozeComponent.class,
ExpandableNotificationRowComponent.class,
- NotificationShelfComponent.class})
+ NotificationShelfComponent.class,
+ FragmentService.FragmentCreator.class})
public abstract class SystemUIModule {
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
new file mode 100644
index 000000000000..929b61a3421c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 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.dagger;
+
+import dagger.Subcomponent;
+
+/**
+ * Dagger Subcomponent for WindowManager.
+ */
+@WMSingleton
+@Subcomponent(modules = {})
+public interface WMComponent {
+
+ /**
+ * Builder for a WMComponent.
+ */
+ @Subcomponent.Builder
+ interface Builder {
+ WMComponent build();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java b/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
new file mode 100644
index 000000000000..2894780e04b8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dagger;
+
+import dagger.Module;
+
+/**
+ * Dagger module for including the WMComponent.
+ */
+@Module(subcomponents = {WMComponent.class})
+public abstract class WMModule {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMSingleton.java b/packages/SystemUI/src/com/android/systemui/dagger/WMSingleton.java
new file mode 100644
index 000000000000..7292b9e459e0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMSingleton.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Scope;
+
+/**
+ * Scope annotation for singleton items within the WMComponent.
+ */
+@Documented
+@Retention(RUNTIME)
+@Scope
+public @interface WMSingleton {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/demomode/DemoMode.java b/packages/SystemUI/src/com/android/systemui/demomode/DemoMode.java
new file mode 100644
index 000000000000..672ade2655a3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/demomode/DemoMode.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.demomode;
+
+import com.google.android.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Interface defining what it means to implement DemoMode. A DemoMode implementation should
+ * register with DemoModeController, providing a list of commands for wish to listen.
+ *
+ * If you only need to listen to commands, but *do not* care about demo mode state changes, you
+ * can implement DemoModeCommandReceiver instead
+ */
+public interface DemoMode extends DemoModeCommandReceiver {
+
+ List<String> NO_COMMANDS = new ArrayList<>();
+
+ /** Provide a set of commands to listen to, only acceptable values are the COMMAND_* keys */
+ default List<String> demoCommands() {
+ return NO_COMMANDS;
+ }
+
+ String ACTION_DEMO = "com.android.systemui.demo";
+
+ String EXTRA_COMMAND = "command";
+
+ /** Enter and exit are non-register-able; override started/finished to observe these states */
+ String COMMAND_ENTER = "enter";
+ String COMMAND_EXIT = "exit";
+
+ /** Observable commands to register a listener for */
+ String COMMAND_CLOCK = "clock";
+ String COMMAND_BATTERY = "battery";
+ String COMMAND_NETWORK = "network";
+ String COMMAND_BARS = "bars";
+ String COMMAND_STATUS = "status";
+ String COMMAND_NOTIFICATIONS = "notifications";
+ String COMMAND_VOLUME = "volume";
+ String COMMAND_OPERATOR = "operator";
+
+ /** New keys need to be added here */
+ List<String> COMMANDS = Lists.newArrayList(
+ COMMAND_BARS,
+ COMMAND_BATTERY,
+ COMMAND_CLOCK,
+ COMMAND_NETWORK,
+ COMMAND_NOTIFICATIONS,
+ COMMAND_OPERATOR,
+ COMMAND_STATUS,
+ COMMAND_VOLUME
+ );
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt b/packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt
new file mode 100644
index 000000000000..16f415070b45
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.demomode
+
+import android.content.Context
+import android.database.ContentObserver
+import android.os.Handler
+import android.os.Looper
+import android.provider.Settings
+
+/**
+ * Class to track the availability of [DemoMode]. Use this class to track the availability and
+ * on/off state for DemoMode
+ *
+ * This class works by wrapping a content observer for the relevant keys related to DemoMode
+ * availability and current on/off state, and triggering callbacks.
+ */
+abstract class DemoModeAvailabilityTracker(val context: Context) {
+ var isInDemoMode = false
+ var isDemoModeAvailable = false
+
+ init {
+ isInDemoMode = checkIsDemoModeOn()
+ isDemoModeAvailable = checkIsDemoModeAllowed()
+ }
+
+ fun startTracking() {
+ val resolver = context.contentResolver
+ resolver.registerContentObserver(
+ Settings.Global.getUriFor(DEMO_MODE_ALLOWED), false, allowedObserver)
+ resolver.registerContentObserver(
+ Settings.Global.getUriFor(DEMO_MODE_ON), false, onObserver)
+ }
+
+ fun stopTracking() {
+ val resolver = context.contentResolver
+ resolver.unregisterContentObserver(allowedObserver)
+ resolver.unregisterContentObserver(onObserver)
+ }
+
+ abstract fun onDemoModeAvailabilityChanged()
+ abstract fun onDemoModeStarted()
+ abstract fun onDemoModeFinished()
+
+ private fun checkIsDemoModeAllowed(): Boolean {
+ return Settings.Global
+ .getInt(context.contentResolver, DEMO_MODE_ALLOWED, 0) != 0
+ }
+
+ private fun checkIsDemoModeOn(): Boolean {
+ return Settings.Global.getInt(context.contentResolver, DEMO_MODE_ON, 0) != 0
+ }
+
+ private val allowedObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {
+ override fun onChange(selfChange: Boolean) {
+ val allowed = checkIsDemoModeAllowed()
+ if (DEBUG) {
+ android.util.Log.d(TAG, "onChange: DEMO_MODE_ALLOWED changed: $allowed")
+ }
+
+ if (isDemoModeAvailable == allowed) {
+ return
+ }
+
+ isDemoModeAvailable = allowed
+ onDemoModeAvailabilityChanged()
+ }
+ }
+
+ private val onObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {
+ override fun onChange(selfChange: Boolean) {
+ val on = checkIsDemoModeOn()
+
+ if (DEBUG) {
+ android.util.Log.d(TAG, "onChange: DEMO_MODE_ON changed: $on")
+ }
+
+ if (isInDemoMode == on) {
+ return
+ }
+
+ isInDemoMode = on
+ if (on) {
+ onDemoModeStarted()
+ } else {
+ onDemoModeFinished()
+ }
+ }
+ }
+}
+
+private const val TAG = "DemoModeAvailabilityTracker"
+private const val DEMO_MODE_ALLOWED = "sysui_demo_allowed"
+private const val DEMO_MODE_ON = "sysui_tuner_demo_on"
+private const val DEBUG = false
diff --git a/packages/SystemUI/src/com/android/systemui/demomode/DemoModeCommandReceiver.java b/packages/SystemUI/src/com/android/systemui/demomode/DemoModeCommandReceiver.java
new file mode 100644
index 000000000000..609536a4b8e8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/demomode/DemoModeCommandReceiver.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.demomode;
+
+import android.os.Bundle;
+
+/** Defines the basic DemoMode command interface */
+public interface DemoModeCommandReceiver {
+ /** Override point to observe demo mode commands */
+ void dispatchDemoCommand(String command, Bundle args);
+
+ /**
+ * Demo mode starts due to receiving [COMMAND_ENTER] or receiving any other demo mode command
+ * while [DEMO_MODE_ALLOWED] is true but demo mode is off
+ */
+ default void onDemoModeStarted() {}
+
+ /** Demo mode exited */
+ default void onDemoModeFinished() {}
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt b/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
new file mode 100644
index 000000000000..c76f55631ac9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.demomode
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.os.Bundle
+import android.os.UserHandle
+import android.util.Log
+import com.android.systemui.Dumpable
+import com.android.systemui.demomode.DemoMode.ACTION_DEMO
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.policy.CallbackController
+import com.android.systemui.util.Assert
+import com.android.systemui.util.settings.GlobalSettings
+import java.io.FileDescriptor
+import java.io.PrintWriter
+
+/**
+ * Handles system broadcasts for [DemoMode]
+ *
+ * Injected via [DemoModeModule]
+ */
+class DemoModeController constructor(
+ private val context: Context,
+ private val dumpManager: DumpManager,
+ private val globalSettings: GlobalSettings
+) : CallbackController<DemoMode>, Dumpable {
+
+ // Var updated when the availability tracker changes, or when we enter/exit demo mode in-process
+ var isInDemoMode = false
+
+ var isAvailable = false
+ get() = tracker.isDemoModeAvailable
+
+ private var initialized = false
+
+ private val receivers = mutableListOf<DemoMode>()
+ private val receiverMap: Map<String, MutableList<DemoMode>>
+
+ init {
+ val m = mutableMapOf<String, MutableList<DemoMode>>()
+ DemoMode.COMMANDS.map { command ->
+ m.put(command, mutableListOf())
+ }
+ receiverMap = m
+ }
+
+ fun initialize() {
+ if (initialized) {
+ throw IllegalStateException("Already initialized")
+ }
+
+ initialized = true
+
+ dumpManager.registerDumpable(TAG, this)
+
+ // Due to DemoModeFragment running in systemui:tuner process, we have to observe for
+ // content changes to know if the setting turned on or off
+ tracker.startTracking()
+
+ // TODO: We should probably exit demo mode if we booted up with it on
+ isInDemoMode = tracker.isInDemoMode
+
+ val demoFilter = IntentFilter()
+ demoFilter.addAction(ACTION_DEMO)
+ context.registerReceiverAsUser(broadcastReceiver, UserHandle.ALL, demoFilter,
+ android.Manifest.permission.DUMP, null)
+ }
+
+ override fun addCallback(listener: DemoMode) {
+ Assert.isMainThread()
+
+ // Register this listener for its commands
+ val commands = listener.demoCommands()
+
+ commands.forEach { command ->
+ if (!receiverMap.containsKey(command)) {
+ throw IllegalStateException("Command ($command) not recognized. " +
+ "See DemoMode.java for valid commands")
+ }
+
+ receiverMap[command]!!.add(listener)
+ }
+
+ receivers.add(listener)
+ if (isInDemoMode) {
+ listener.onDemoModeStarted()
+ }
+ }
+
+ override fun removeCallback(listener: DemoMode) {
+ Assert.isMainThread()
+
+ listener.demoCommands().forEach { command ->
+ receiverMap[command]!!.remove(listener)
+ }
+
+ receivers.remove(listener)
+ }
+
+ private fun setIsDemoModeAllowed(enabled: Boolean) {
+ // Turn off demo mode if it was on
+ if (isInDemoMode && !enabled) {
+ requestFinishDemoMode()
+ }
+ }
+
+ private fun enterDemoMode() {
+ isInDemoMode = true
+ Assert.isMainThread()
+ receivers.forEach { r ->
+ r.onDemoModeStarted()
+ }
+ }
+
+ private fun exitDemoMode() {
+ isInDemoMode = false
+ Assert.isMainThread()
+ receivers.forEach { r ->
+ r.onDemoModeFinished()
+ }
+ }
+
+ fun dispatchDemoCommand(command: String, args: Bundle) {
+ Assert.isMainThread()
+
+ if (DEBUG) {
+ Log.d(TAG, "dispatchDemoCommand: $command, args=$args")
+ }
+
+ if (!isAvailable) {
+ return
+ }
+
+ if (command == DemoMode.COMMAND_ENTER) {
+ enterDemoMode()
+ } else if (command == DemoMode.COMMAND_EXIT) {
+ exitDemoMode()
+ } else if (!isInDemoMode) {
+ enterDemoMode()
+ }
+
+ // See? demo mode is easy now, you just notify the listeners when their command is called
+ receiverMap[command]!!.forEach { receiver ->
+ receiver.dispatchDemoCommand(command, args)
+ }
+ }
+
+ override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
+ pw.println("DemoModeController state -")
+ pw.println(" isInDemoMode=$isInDemoMode")
+ pw.println(" isDemoModeAllowed=$isAvailable")
+ pw.print(" receivers=[")
+ receivers.forEach { recv ->
+ pw.print(" ${recv.javaClass.simpleName}")
+ }
+ pw.println(" ]")
+ pw.println(" receiverMap= [")
+ receiverMap.keys.forEach { command ->
+ pw.print(" $command : [")
+ val recvs = receiverMap[command]!!.map { receiver ->
+ receiver.javaClass.simpleName
+ }.joinToString(",")
+ pw.println("$recvs ]")
+ }
+ }
+
+ private val tracker = object : DemoModeAvailabilityTracker(context) {
+ override fun onDemoModeAvailabilityChanged() {
+ setIsDemoModeAllowed(isDemoModeAvailable)
+ }
+
+ override fun onDemoModeStarted() {
+ if (this@DemoModeController.isInDemoMode != isInDemoMode) {
+ enterDemoMode()
+ }
+ }
+
+ override fun onDemoModeFinished() {
+ if (this@DemoModeController.isInDemoMode != isInDemoMode) {
+ exitDemoMode()
+ }
+ }
+ }
+
+ private val broadcastReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ if (DEBUG) {
+ Log.v(TAG, "onReceive: $intent")
+ }
+
+ val action = intent.action
+ if (!ACTION_DEMO.equals(action)) {
+ return
+ }
+
+ val bundle = intent.extras ?: return
+ val command = bundle.getString("command", "").trim().toLowerCase()
+ if (command.length == 0) {
+ return
+ }
+
+ try {
+ dispatchDemoCommand(command, bundle)
+ } catch (t: Throwable) {
+ Log.w(TAG, "Error running demo command, intent=$intent $t")
+ }
+ }
+ }
+
+ fun requestSetDemoModeAllowed(allowed: Boolean) {
+ setGlobal(DEMO_MODE_ALLOWED, if (allowed) 1 else 0)
+ }
+
+ fun requestStartDemoMode() {
+ setGlobal(DEMO_MODE_ON, 1)
+ }
+
+ fun requestFinishDemoMode() {
+ setGlobal(DEMO_MODE_ON, 0)
+ }
+
+ private fun setGlobal(key: String, value: Int) {
+ globalSettings.putInt(key, value)
+ }
+}
+
+private const val TAG = "DemoModeController"
+private const val DEMO_MODE_ALLOWED = "sysui_demo_allowed"
+private const val DEMO_MODE_ON = "sysui_tuner_demo_on"
+
+private const val DEBUG = false
diff --git a/packages/SystemUI/src/com/android/systemui/demomode/dagger/DemoModeModule.java b/packages/SystemUI/src/com/android/systemui/demomode/dagger/DemoModeModule.java
new file mode 100644
index 000000000000..9270b8843c80
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/demomode/dagger/DemoModeModule.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.demomode.dagger;
+
+import android.content.Context;
+
+import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.util.settings.GlobalSettings;
+
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Dagger module providing {@link DemoModeController}
+ */
+@Module
+public abstract class DemoModeModule {
+ /** Provides DemoModeController */
+ @Provides
+ @Singleton
+ static DemoModeController provideDemoModeController(
+ Context context,
+ DumpManager dumpManager,
+ GlobalSettings globalSettings) {
+ DemoModeController dmc = new DemoModeController(context, dumpManager, globalSettings);
+ dmc.initialize();
+ return /*run*/dmc;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
index ae200763b3b0..e88886933d5f 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentService.java
@@ -21,9 +21,7 @@ import android.util.ArrayMap;
import android.view.View;
import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.SystemUIRootComponent;
import com.android.systemui.qs.QSFragment;
-import com.android.systemui.statusbar.phone.NavigationBarFragment;
import com.android.systemui.statusbar.policy.ConfigurationController;
import java.io.FileDescriptor;
@@ -61,9 +59,9 @@ public class FragmentService implements Dumpable {
};
@Inject
- public FragmentService(SystemUIRootComponent rootComponent,
+ public FragmentService(FragmentCreator.Factory fragmentCreatorFactory,
ConfigurationController configurationController) {
- mFragmentCreator = rootComponent.createFragmentCreator();
+ mFragmentCreator = fragmentCreatorFactory.build();
initInjectionMap();
configurationController.addCallback(mConfigurationListener);
}
@@ -121,10 +119,11 @@ public class FragmentService implements Dumpable {
*/
@Subcomponent
public interface FragmentCreator {
- /**
- * Inject a NavigationBarFragment.
- */
- NavigationBarFragment createNavigationBarFragment();
+ /** Factory for creating a FragmentCreator. */
+ @Subcomponent.Factory
+ interface Factory {
+ FragmentCreator build();
+ }
/**
* Inject a QSFragment.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index 3a37c0fd4634..daef2c506ad3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -52,7 +52,6 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SystemUIAppComponentFactory;
-import com.android.systemui.SystemUIFactory;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.StatusBarState;
@@ -72,6 +71,9 @@ import javax.inject.Inject;
/**
* Simple Slice provider that shows the current date.
+ *
+ * Injection is handled by {@link SystemUIAppComponentFactory} +
+ * {@link com.android.systemui.dagger.GlobalRootComponent#inject(KeyguardSliceProvider)}.
*/
public class KeyguardSliceProvider extends SliceProvider implements
NextAlarmController.NextAlarmChangeCallback, ZenModeController.Callback,
@@ -298,7 +300,8 @@ public class KeyguardSliceProvider extends SliceProvider implements
@Override
public boolean onCreateSliceProvider() {
mContextAvailableCallback.onContextAvailable(getContext());
- inject();
+ mMediaWakeLock = new SettableWakeLock(WakeLock.createPartial(getContext(), "media"),
+ "media");
synchronized (KeyguardSliceProvider.sInstanceLock) {
KeyguardSliceProvider oldInstance = KeyguardSliceProvider.sInstance;
if (oldInstance != null) {
@@ -319,13 +322,6 @@ public class KeyguardSliceProvider extends SliceProvider implements
}
@VisibleForTesting
- protected void inject() {
- SystemUIFactory.getInstance().getRootComponent().inject(this);
- mMediaWakeLock = new SettableWakeLock(WakeLock.createPartial(getContext(), "media"),
- "media");
- }
-
- @VisibleForTesting
protected void onDestroy() {
synchronized (KeyguardSliceProvider.sInstanceLock) {
mNextAlarmController.removeCallback(this);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 75f4809d752f..6214a6448287 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -85,7 +85,6 @@ import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
-import com.android.systemui.SystemUIFactory;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.dump.DumpManager;
@@ -94,7 +93,7 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.DeviceConfigProxy;
@@ -229,6 +228,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
/** TrustManager for letting it know when we change visibility */
private final TrustManager mTrustManager;
+ private final InjectionInflationController mInjectionInflationController;
/**
* Used to keep the device awake while to ensure the keyguard finishes opening before
@@ -723,7 +723,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
@UiBackground Executor uiBgExecutor, PowerManager powerManager,
TrustManager trustManager,
DeviceConfigProxy deviceConfig,
- NavigationModeController navigationModeController) {
+ NavigationModeController navigationModeController,
+ InjectionInflationController injectionInflationController) {
super(context);
mFalsingManager = falsingManager;
mLockPatternUtils = lockPatternUtils;
@@ -734,6 +735,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
mUpdateMonitor = keyguardUpdateMonitor;
mPM = powerManager;
mTrustManager = trustManager;
+ mInjectionInflationController = injectionInflationController;
dumpManager.registerDumpable(getClass().getName(), this);
mDeviceConfig = deviceConfig;
mShowHomeOverLockscreen = mDeviceConfig.getBoolean(
@@ -773,10 +775,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable {
mContext.registerReceiver(mDelayedLockBroadcastReceiver, delayedActionFilter,
SYSTEMUI_PERMISSION, null /* scheduler */);
- InjectionInflationController injectionInflationController =
- new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent());
mKeyguardDisplayManager = new KeyguardDisplayManager(mContext,
- injectionInflationController);
+ mInjectionInflationController);
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index 83c95b77b716..fc789a6fa4bc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -29,9 +29,10 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.DeviceConfigProxy;
+import com.android.systemui.util.InjectionInflationController;
import java.util.concurrent.Executor;
@@ -64,7 +65,8 @@ public class KeyguardModule {
TrustManager trustManager,
@UiBackground Executor uiBgExecutor,
DeviceConfigProxy deviceConfig,
- NavigationModeController navigationModeController) {
+ NavigationModeController navigationModeController,
+ InjectionInflationController injectionInflationController) {
return new KeyguardViewMediator(
context,
falsingManager,
@@ -78,6 +80,7 @@ public class KeyguardModule {
powerManager,
trustManager,
deviceConfig,
- navigationModeController);
+ navigationModeController,
+ injectionInflationController);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 7f610d1a8467..b993faabe9b1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -10,6 +10,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
+import androidx.annotation.VisibleForTesting
import com.android.systemui.R
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
@@ -21,6 +22,7 @@ import com.android.systemui.util.Utils
import com.android.systemui.util.animation.UniqueObjectHostView
import com.android.systemui.util.animation.requiresRemeasuring
import com.android.systemui.util.concurrency.DelayableExecutor
+import java.util.TreeMap
import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton
@@ -102,9 +104,7 @@ class MediaCarouselController @Inject constructor(
private val mediaCarousel: MediaScrollView
private val mediaCarouselScrollHandler: MediaCarouselScrollHandler
val mediaFrame: ViewGroup
- val mediaPlayers: MutableMap<String, MediaControlPanel> = mutableMapOf()
private lateinit var settingsButton: View
- private val mediaData: MutableMap<String, MediaData> = mutableMapOf()
private val mediaContent: ViewGroup
private val pageIndicator: PageIndicator
private val visualStabilityCallback: VisualStabilityManager.Callback
@@ -122,7 +122,7 @@ class MediaCarouselController @Inject constructor(
set(value) {
if (field != value) {
field = value
- for (player in mediaPlayers.values) {
+ for (player in MediaPlayerData.players()) {
player.setListening(field)
}
}
@@ -167,20 +167,18 @@ class MediaCarouselController @Inject constructor(
true /* persistent */)
mediaManager.addListener(object : MediaDataManager.Listener {
override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) {
- oldKey?.let { mediaData.remove(it) }
if (!data.active && !Utils.useMediaResumption(context)) {
// This view is inactive, let's remove this! This happens e.g when dismissing /
// timing out a view. We still have the data around because resumption could
// be on, but we should save the resources and release this.
+ oldKey?.let { MediaPlayerData.removeMediaPlayer(it) }
onMediaDataRemoved(key)
} else {
- mediaData.put(key, data)
addOrUpdatePlayer(key, oldKey, data)
}
}
override fun onMediaDataRemoved(key: String) {
- mediaData.remove(key)
removePlayer(key)
}
})
@@ -223,53 +221,36 @@ class MediaCarouselController @Inject constructor(
}
private fun reorderAllPlayers() {
- for (mediaPlayer in mediaPlayers.values) {
- val view = mediaPlayer.view?.player
- if (mediaPlayer.isPlaying && mediaContent.indexOfChild(view) != 0) {
- mediaContent.removeView(view)
- mediaContent.addView(view, 0)
+ mediaContent.removeAllViews()
+ for (mediaPlayer in MediaPlayerData.players()) {
+ mediaPlayer.view?.let {
+ mediaContent.addView(it.player)
}
}
mediaCarouselScrollHandler.onPlayersChanged()
}
private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData) {
- // If the key was changed, update entry
- val oldData = mediaPlayers[oldKey]
- if (oldData != null) {
- val oldData = mediaPlayers.remove(oldKey)
- mediaPlayers.put(key, oldData!!)?.let {
- Log.wtf(TAG, "new key $key already exists when migrating from $oldKey")
- }
- }
- var existingPlayer = mediaPlayers[key]
+ val existingPlayer = MediaPlayerData.getMediaPlayer(key, oldKey)
if (existingPlayer == null) {
- existingPlayer = mediaControlPanelFactory.get()
- existingPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context),
- mediaContent))
- existingPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
- mediaPlayers[key] = existingPlayer
+ var newPlayer = mediaControlPanelFactory.get()
+ newPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context), mediaContent))
+ newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
+ MediaPlayerData.addMediaPlayer(key, data, newPlayer)
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
- existingPlayer.view?.player?.setLayoutParams(lp)
- existingPlayer.bind(data)
- existingPlayer.setListening(currentlyExpanded)
- updatePlayerToState(existingPlayer, noAnimation = true)
- if (existingPlayer.isPlaying) {
- mediaContent.addView(existingPlayer.view?.player, 0)
- } else {
- mediaContent.addView(existingPlayer.view?.player)
- }
+ newPlayer.view?.player?.setLayoutParams(lp)
+ newPlayer.bind(data)
+ newPlayer.setListening(currentlyExpanded)
+ updatePlayerToState(newPlayer, noAnimation = true)
+ reorderAllPlayers()
} else {
existingPlayer.bind(data)
- if (existingPlayer.isPlaying &&
- mediaContent.indexOfChild(existingPlayer.view?.player) != 0) {
- if (visualStabilityManager.isReorderingAllowed) {
- mediaContent.removeView(existingPlayer.view?.player)
- mediaContent.addView(existingPlayer.view?.player, 0)
- } else {
- needsReordering = true
- }
+ MediaPlayerData.addMediaPlayer(key, data, existingPlayer)
+ if (visualStabilityManager.isReorderingAllowed) {
+ reorderAllPlayers()
+ } else {
+ needsReordering = true
}
}
updatePageIndicator()
@@ -277,13 +258,13 @@ class MediaCarouselController @Inject constructor(
mediaCarousel.requiresRemeasuring = true
// Check postcondition: mediaContent should have the same number of children as there are
// elements in mediaPlayers.
- if (mediaPlayers.size != mediaContent.childCount) {
+ if (MediaPlayerData.players().size != mediaContent.childCount) {
Log.wtf(TAG, "Size of players list and number of views in carousel are out of sync")
}
}
private fun removePlayer(key: String) {
- val removed = mediaPlayers.remove(key)
+ val removed = MediaPlayerData.removeMediaPlayer(key)
removed?.apply {
mediaCarouselScrollHandler.onPrePlayerRemoved(removed)
mediaContent.removeView(removed.view?.player)
@@ -294,12 +275,7 @@ class MediaCarouselController @Inject constructor(
}
private fun recreatePlayers() {
- // Note that this will scramble the order of players. Actively playing sessions will, at
- // least, still be put in the front. If we want to maintain order, then more work is
- // needed.
- mediaData.forEach {
- key, data ->
- removePlayer(key)
+ MediaPlayerData.mediaData().forEach { (key, data) ->
addOrUpdatePlayer(key = key, oldKey = null, data = data)
}
}
@@ -337,7 +313,7 @@ class MediaCarouselController @Inject constructor(
currentStartLocation = startLocation
currentEndLocation = endLocation
currentTransitionProgress = progress
- for (mediaPlayer in mediaPlayers.values) {
+ for (mediaPlayer in MediaPlayerData.players()) {
updatePlayerToState(mediaPlayer, immediately)
}
maybeResetSettingsCog()
@@ -386,7 +362,7 @@ class MediaCarouselController @Inject constructor(
private fun updateCarouselDimensions() {
var width = 0
var height = 0
- for (mediaPlayer in mediaPlayers.values) {
+ for (mediaPlayer in MediaPlayerData.players()) {
val controller = mediaPlayer.mediaViewController
// When transitioning the view to gone, the view gets smaller, but the translation
// Doesn't, let's add the translation
@@ -448,7 +424,7 @@ class MediaCarouselController @Inject constructor(
this.desiredLocation = desiredLocation
this.desiredHostState = it
currentlyExpanded = it.expansion > 0
- for (mediaPlayer in mediaPlayers.values) {
+ for (mediaPlayer in MediaPlayerData.players()) {
if (animate) {
mediaPlayer.mediaViewController.animatePendingStateChange(
duration = duration,
@@ -470,7 +446,7 @@ class MediaCarouselController @Inject constructor(
}
fun closeGuts() {
- mediaPlayers.values.forEach {
+ MediaPlayerData.players().forEach {
it.closeGuts(true)
}
}
@@ -497,3 +473,50 @@ class MediaCarouselController @Inject constructor(
}
}
}
+
+@VisibleForTesting
+internal object MediaPlayerData {
+ private data class MediaSortKey(
+ val data: MediaData,
+ val updateTime: Long = 0,
+ val isPlaying: Boolean = false
+ )
+
+ private val comparator =
+ compareByDescending<MediaSortKey> { it.isPlaying }
+ .thenByDescending { it.data.isLocalSession }
+ .thenByDescending { !it.data.resumption }
+ .thenByDescending { it.updateTime }
+
+ private val mediaPlayers = TreeMap<MediaSortKey, MediaControlPanel>(comparator)
+ private val mediaData: MutableMap<String, MediaSortKey> = mutableMapOf()
+
+ fun addMediaPlayer(key: String, data: MediaData, player: MediaControlPanel) {
+ removeMediaPlayer(key)
+ val sortKey = MediaSortKey(data, System.currentTimeMillis(), player.isPlaying())
+ mediaData.put(key, sortKey)
+ mediaPlayers.put(sortKey, player)
+ }
+
+ fun getMediaPlayer(key: String, oldKey: String?): MediaControlPanel? {
+ // If the key was changed, update entry
+ oldKey?.let {
+ if (it != key) {
+ mediaData.remove(it)?.let { sortKey -> mediaData.put(key, sortKey) }
+ }
+ }
+ return mediaData.get(key)?.let { mediaPlayers.get(it) }
+ }
+
+ fun removeMediaPlayer(key: String) = mediaData.remove(key)?.let { mediaPlayers.remove(it) }
+
+ fun mediaData() = mediaData.entries.map { e -> Pair(e.key, e.value.data) }
+
+ fun players() = mediaPlayers.values
+
+ @VisibleForTesting
+ fun clear() {
+ mediaData.clear()
+ mediaPlayers.clear()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index dafc52ad8025..d6a02687c905 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -82,6 +82,10 @@ data class MediaData(
*/
var resumeAction: Runnable?,
/**
+ * Local or remote playback
+ */
+ var isLocalSession: Boolean = true,
+ /**
* Indicates that this player is a resumption player (ie. It only shows a play actions which
* will start the app and start playing).
*/
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index e77e499223aa..bff334e92366 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -31,6 +31,7 @@ import android.graphics.drawable.Drawable
import android.graphics.drawable.Icon
import android.media.MediaDescription
import android.media.MediaMetadata
+import android.media.session.MediaController
import android.media.session.MediaSession
import android.net.Uri
import android.os.UserHandle
@@ -56,6 +57,8 @@ import java.io.PrintWriter
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Singleton
+import kotlin.collections.ArrayList
+import kotlin.collections.LinkedHashMap
// URI fields to try loading album art from
private val ART_URIS = arrayOf(
@@ -105,6 +108,17 @@ class MediaDataManager(
private val listeners: MutableSet<Listener> = mutableSetOf()
private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
+ internal var appsBlockedFromResume: MutableSet<String> = Utils.getBlockedMediaApps(context)
+ set(value) {
+ // Update list
+ appsBlockedFromResume.clear()
+ appsBlockedFromResume.addAll(value)
+
+ // Remove any existing resume players that are now blocked
+ appsBlockedFromResume.forEach {
+ removeAllForPackage(it)
+ }
+ }
@Inject
constructor(
@@ -331,7 +345,8 @@ class MediaDataManager(
) {
val token = sbn.notification.extras.getParcelable(Notification.EXTRA_MEDIA_SESSION)
as MediaSession.Token?
- val metadata = mediaControllerFactory.create(token).metadata
+ val mediaController = mediaControllerFactory.create(token)
+ val metadata = mediaController.metadata
// Foreground and Background colors computed from album art
val notif: Notification = sbn.notification
@@ -426,6 +441,9 @@ class MediaDataManager(
}
}
+ val isLocalSession = mediaController.playbackInfo?.playbackType ==
+ MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL ?: true
+
foregroundExecutor.execute {
val resumeAction: Runnable? = mediaEntries[key]?.resumeAction
val hasCheckedForResume = mediaEntries[key]?.hasCheckedForResume == true
@@ -433,8 +451,8 @@ class MediaDataManager(
onMediaDataLoaded(key, oldKey, MediaData(sbn.normalizedUserId, true, bgColor, app,
smallIconDrawable, artist, song, artWorkIcon, actionIcons,
actionsToShowCollapsed, sbn.packageName, token, notif.contentIntent, null,
- active, resumeAction = resumeAction, notificationKey = key,
- hasCheckedForResume = hasCheckedForResume))
+ active, resumeAction = resumeAction, isLocalSession = isLocalSession,
+ notificationKey = key, hasCheckedForResume = hasCheckedForResume))
}
}
@@ -542,8 +560,9 @@ class MediaDataManager(
fun onNotificationRemoved(key: String) {
Assert.isMainThread()
val removed = mediaEntries.remove(key)
- if (useMediaResumption && removed?.resumeAction != null) {
- if (DEBUG) Log.d(TAG, "Not removing $key because resumable")
+ if (useMediaResumption && removed?.resumeAction != null &&
+ !isBlockedFromResume(removed?.packageName)) {
+ Log.d(TAG, "Not removing $key because resumable")
// Move to resume key (aka package name) if that key doesn't already exist.
val resumeAction = getResumeMediaAction(removed.resumeAction!!)
val updated = removed.copy(token = null, actions = listOf(resumeAction),
@@ -579,6 +598,13 @@ class MediaDataManager(
}
}
+ private fun isBlockedFromResume(packageName: String?): Boolean {
+ if (packageName == null) {
+ return true
+ }
+ return appsBlockedFromResume.contains(packageName)
+ }
+
fun setMediaResumptionEnabled(isEnabled: Boolean) {
if (useMediaResumption == isEnabled) {
return
@@ -621,6 +647,7 @@ class MediaDataManager(
println("listeners: $listeners")
println("mediaEntries: $mediaEntries")
println("useMediaResumption: $useMediaResumption")
+ println("appsBlockedFromResume: $appsBlockedFromResume")
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
index 4ec746fcb153..c41712c4cf10 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
@@ -52,6 +52,7 @@ class MediaResumeListener @Inject constructor(
private var useMediaResumption: Boolean = Utils.useMediaResumption(context)
private val resumeComponents: ConcurrentLinkedQueue<ComponentName> = ConcurrentLinkedQueue()
+ private var blockedApps: MutableSet<String> = Utils.getBlockedMediaApps(context)
private lateinit var mediaDataManager: MediaDataManager
@@ -114,6 +115,14 @@ class MediaResumeListener @Inject constructor(
mediaDataManager.setMediaResumptionEnabled(useMediaResumption)
}
}, Settings.Secure.MEDIA_CONTROLS_RESUME)
+
+ // Listen to changes in which apps are allowed to persist
+ tunerService.addTunable(object : TunerService.Tunable {
+ override fun onTuningChanged(key: String?, newValue: String?) {
+ blockedApps = Utils.getBlockedMediaApps(context)
+ mediaDataManager.appsBlockedFromResume = blockedApps
+ }
+ }, Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED)
}
fun isResumptionEnabled() = useMediaResumption
@@ -144,8 +153,10 @@ class MediaResumeListener @Inject constructor(
}
resumeComponents.forEach {
- val browser = ResumeMediaBrowser(context, mediaBrowserCallback, it)
- browser.findRecentMedia()
+ if (!blockedApps.contains(it.packageName)) {
+ val browser = ResumeMediaBrowser(context, mediaBrowserCallback, it)
+ browser.findRecentMedia()
+ }
}
}
@@ -154,7 +165,8 @@ class MediaResumeListener @Inject constructor(
// If this had been started from a resume state, disconnect now that it's live
mediaBrowser?.disconnect()
// If we don't have a resume action, check if we haven't already
- if (data.resumeAction == null && !data.hasCheckedForResume) {
+ if (data.resumeAction == null && !data.hasCheckedForResume &&
+ !blockedApps.contains(data.packageName)) {
// TODO also check for a media button receiver intended for restarting (b/154127084)
Log.d(TAG, "Checking for service component for " + data.packageName)
val pm = context.packageManager
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index fd653b4e8aa5..6c8a23ba96d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -1,18 +1,20 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
@@ -21,6 +23,7 @@ import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.WindowType;
import static android.app.StatusBarManager.WindowVisibleState;
import static android.app.StatusBarManager.windowStateToString;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.containsType;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
@@ -78,17 +81,16 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
+import android.view.IWindowManager;
import android.view.InsetsState.InternalInsetsType;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
-import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowInsetsController.Appearance;
import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
@@ -102,6 +104,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
import com.android.internal.view.AppearanceRegion;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.assist.AssistHandleViewController;
@@ -109,8 +112,12 @@ import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.fragments.FragmentHostManager;
-import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.buttons.RotationContextButton;
+import com.android.systemui.navigationbar.gestural.QuickswitchOrientedNavHandle;
+import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
@@ -123,29 +130,28 @@ import com.android.systemui.statusbar.CommandQueue.Callbacks;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
-import com.android.systemui.statusbar.phone.ContextualButton.ContextButtonListener;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.KeyButtonView;
-import com.android.systemui.util.LifecycleFragment;
-import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.function.Consumer;
-import javax.inject.Inject;
-
import dagger.Lazy;
/**
- * Fragment containing the NavigationBarFragment. Contains logic for what happens
- * on clicks and view states of the nav bar.
+ * Contains logic for a navigation bar view.
*/
-public class NavigationBarFragment extends LifecycleFragment implements Callbacks,
- NavigationModeController.ModeChangedListener, DisplayManager.DisplayListener {
+public class NavigationBar implements View.OnAttachStateChangeListener,
+ Callbacks, NavigationModeController.ModeChangedListener, DisplayManager.DisplayListener {
public static final String TAG = "NavigationBar";
private static final boolean DEBUG = false;
@@ -158,35 +164,41 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
private static final long AUTODIM_TIMEOUT_MS = 2250;
+ private final Context mContext;
+ private final WindowManager mWindowManager;
+ private final AccessibilityManager mAccessibilityManager;
private final AccessibilityManagerWrapper mAccessibilityManagerWrapper;
- protected final AssistManager mAssistManager;
- private SysUiState mSysUiFlagsContainer;
- private final MetricsLogger mMetricsLogger;
private final DeviceProvisionedController mDeviceProvisionedController;
private final StatusBarStateController mStatusBarStateController;
+ private final MetricsLogger mMetricsLogger;
+ private final Lazy<AssistManager> mAssistManagerLazy;
+ private final SysUiState mSysUiFlagsContainer;
+ private final Lazy<StatusBar> mStatusBarLazy;
+ private final ShadeController mShadeController;
+ private final NotificationRemoteInputManager mNotificationRemoteInputManager;
+ private final OverviewProxyService mOverviewProxyService;
private final NavigationModeController mNavigationModeController;
+ private final BroadcastDispatcher mBroadcastDispatcher;
+ private final CommandQueue mCommandQueue;
+ private final Divider mDivider;
+ private final Optional<Recents> mRecentsOptional;
+ private final SystemActions mSystemActions;
+ private final Handler mHandler;
+ private final UiEventLogger mUiEventLogger;
- protected NavigationBarView mNavigationBarView = null;
+ private Bundle mSavedState;
+ private NavigationBarView mNavigationBarView = null;
private @WindowVisibleState int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
private int mNavigationIconHints = 0;
private @TransitionMode int mNavigationBarMode;
- private AccessibilityManager mAccessibilityManager;
private ContentResolver mContentResolver;
private boolean mAssistantAvailable;
private int mDisabledFlags1;
private int mDisabledFlags2;
- private final Lazy<StatusBar> mStatusBarLazy;
- private final ShadeController mShadeController;
- private final NotificationRemoteInputManager mNotificationRemoteInputManager;
- private final Divider mDivider;
- private final Optional<Recents> mRecentsOptional;
- private WindowManager mWindowManager;
- private final CommandQueue mCommandQueue;
private long mLastLockToAppLongPress;
- private final SystemActions mSystemActions;
private Locale mLocale;
private int mLayoutDirection;
@@ -202,10 +214,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
private LightBarController mLightBarController;
private AutoHideController mAutoHideController;
- private OverviewProxyService mOverviewProxyService;
-
- private final BroadcastDispatcher mBroadcastDispatcher;
-
@VisibleForTesting
public int mDisplayId;
private boolean mIsOnDefaultDisplay;
@@ -226,7 +234,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
private int mStartingQuickSwitchRotation = -1;
private int mCurrentRotation;
private ViewTreeObserver.OnGlobalLayoutListener mOrientationHandleGlobalLayoutListener;
- private UiEventLogger mUiEventLogger;
private boolean mShowOrientedHandleForImmersiveMode;
@com.android.internal.annotations.VisibleForTesting
@@ -251,7 +258,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
@Nullable
private AssistHandleViewController mAssistHandlerViewController;
- private final Handler mHandler;
private final AutoHideUiElement mAutoHideUiElement = new AutoHideUiElement() {
@Override
@@ -307,7 +313,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
@Override
public void startAssistant(Bundle bundle) {
- mAssistManager.startAssist(bundle);
+ mAssistManagerLazy.get().startAssist(bundle);
}
@Override
@@ -360,7 +366,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange, Uri uri) {
- boolean available = mAssistManager
+ boolean available = mAssistManagerLazy.get()
.getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
if (mAssistantAvailable != available) {
sendAssistantAvailability(available);
@@ -369,34 +375,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
};
- private static class NavBarViewAttachedListener implements View.OnAttachStateChangeListener {
- private NavigationBarFragment mFragment;
- private FragmentListener mListener;
-
- NavBarViewAttachedListener(NavigationBarFragment fragment, FragmentListener listener) {
- mFragment = fragment;
- mListener = listener;
- }
-
- @Override
- public void onViewAttachedToWindow(View v) {
- final FragmentHostManager fragmentHost = FragmentHostManager.get(v);
- fragmentHost.getFragmentManager().beginTransaction()
- .replace(R.id.navigation_bar_frame, mFragment, TAG)
- .commit();
- fragmentHost.addTagListener(TAG, mListener);
- mFragment = null;
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- final FragmentHostManager fragmentHost = FragmentHostManager.get(v);
- fragmentHost.removeTagListener(TAG, mListener);
- FragmentHostManager.removeAndDestroy(v);
- v.removeOnAttachStateChangeListener(this);
- }
- }
-
private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
new DeviceConfig.OnPropertiesChangedListener() {
@Override
@@ -416,10 +394,14 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
};
- @Inject
- public NavigationBarFragment(AccessibilityManagerWrapper accessibilityManagerWrapper,
- DeviceProvisionedController deviceProvisionedController, MetricsLogger metricsLogger,
- AssistManager assistManager, OverviewProxyService overviewProxyService,
+ public NavigationBar(Context context,
+ WindowManager windowManager,
+ Lazy<AssistManager> assistManagerLazy,
+ AccessibilityManager accessibilityManager,
+ AccessibilityManagerWrapper accessibilityManagerWrapper,
+ DeviceProvisionedController deviceProvisionedController,
+ MetricsLogger metricsLogger,
+ OverviewProxyService overviewProxyService,
NavigationModeController navigationModeController,
StatusBarStateController statusBarStateController,
SysUiState sysUiFlagsContainer,
@@ -431,16 +413,18 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
SystemActions systemActions,
@Main Handler mainHandler,
UiEventLogger uiEventLogger) {
+ mContext = context;
+ mWindowManager = windowManager;
+ mAccessibilityManager = accessibilityManager;
mAccessibilityManagerWrapper = accessibilityManagerWrapper;
mDeviceProvisionedController = deviceProvisionedController;
mStatusBarStateController = statusBarStateController;
mMetricsLogger = metricsLogger;
- mAssistManager = assistManager;
+ mAssistManagerLazy = assistManagerLazy;
mSysUiFlagsContainer = sysUiFlagsContainer;
mStatusBarLazy = statusBarLazy;
mShadeController = shadeController;
mNotificationRemoteInputManager = notificationRemoteInputManager;
- mAssistantAvailable = mAssistManager.getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
mOverviewProxyService = overviewProxyService;
mNavigationModeController = navigationModeController;
mNavBarMode = navigationModeController.addListener(this);
@@ -453,25 +437,53 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
mUiEventLogger = uiEventLogger;
}
- // ----- Fragment Lifecycle Callbacks -----
+ public View getView() {
+ return mNavigationBarView;
+ }
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mCommandQueue.observe(getLifecycle(), this);
- mWindowManager = getContext().getSystemService(WindowManager.class);
- mAccessibilityManager = getContext().getSystemService(AccessibilityManager.class);
- mContentResolver = getContext().getContentResolver();
+ public View createView(Bundle savedState) {
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT,
+ WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
+ WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+ | WindowManager.LayoutParams.FLAG_SLIPPERY,
+ PixelFormat.TRANSLUCENT);
+ lp.token = new Binder();
+ lp.setTitle("NavigationBar" + mContext.getDisplayId());
+ lp.accessibilityTitle = mContext.getString(R.string.nav_bar);
+ lp.windowAnimations = 0;
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
+
+ LayoutInflater layoutInflater = LayoutInflater.from(mContext);
+ NavigationBarFrame frame = (NavigationBarFrame) layoutInflater.inflate(
+ R.layout.navigation_bar_window, null);
+ View barView = layoutInflater.inflate(R.layout.navigation_bar, frame);
+ barView.addOnAttachStateChangeListener(this);
+
+ if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + barView);
+ mContext.getSystemService(WindowManager.class).addView(frame, lp);
+ mDisplayId = mContext.getDisplayId();
+ mIsOnDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
+
+ mCommandQueue.addCallback(this);
+ mAssistantAvailable = mAssistManagerLazy.get()
+ .getAssistInfoForUser(UserHandle.USER_CURRENT) != null;
+ mContentResolver = mContext.getContentResolver();
mContentResolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.ASSISTANT),
false /* notifyForDescendants */, mAssistContentObserver, UserHandle.USER_ALL);
- if (savedInstanceState != null) {
- mDisabledFlags1 = savedInstanceState.getInt(EXTRA_DISABLE_STATE, 0);
- mDisabledFlags2 = savedInstanceState.getInt(EXTRA_DISABLE2_STATE, 0);
- mAppearance = savedInstanceState.getInt(EXTRA_APPEARANCE, 0);
- mTransientShown = savedInstanceState.getBoolean(EXTRA_TRANSIENT_STATE, false);
+ if (savedState != null) {
+ mDisabledFlags1 = savedState.getInt(EXTRA_DISABLE_STATE, 0);
+ mDisabledFlags2 = savedState.getInt(EXTRA_DISABLE2_STATE, 0);
+ mAppearance = savedState.getInt(EXTRA_APPEARANCE, 0);
+ mTransientShown = savedState.getBoolean(EXTRA_TRANSIENT_STATE, false);
}
+ mSavedState = savedState;
mAccessibilityManagerWrapper.addCallback(mAccessibilityListener);
// Respect the latest disabled-flags.
@@ -486,12 +498,16 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
mIsCurrentUserSetup = mDeviceProvisionedController.isCurrentUserSetup();
mDeviceProvisionedController.addCallback(mUserSetupListener);
+
+ return barView;
}
- @Override
- public void onDestroy() {
- super.onDestroy();
+ public void destroyView() {
+ mCommandQueue.removeCallback(this);
+ mContext.getSystemService(WindowManager.class).removeViewImmediate(
+ mNavigationBarView.getRootView());
mNavigationModeController.removeListener(this);
+
mAccessibilityManagerWrapper.removeCallback(mAccessibilityListener);
mContentResolver.unregisterContentObserver(mAssistContentObserver);
mDeviceProvisionedController.removeCallback(mUserSetupListener);
@@ -500,28 +516,15 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
@Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
- Bundle savedInstanceState) {
- return inflater.inflate(R.layout.navigation_bar, container, false);
- }
-
- @Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- mNavigationBarView = (NavigationBarView) view;
- final Display display = view.getDisplay();
- // It may not have display when running unit test.
- if (display != null) {
- mDisplayId = display.getDisplayId();
- mIsOnDefaultDisplay = mDisplayId == Display.DEFAULT_DISPLAY;
- }
-
+ public void onViewAttachedToWindow(View v) {
+ final Display display = v.getDisplay();
+ mNavigationBarView = v.findViewById(R.id.navigation_bar_view);
mNavigationBarView.setComponents(mStatusBarLazy.get().getPanelController());
mNavigationBarView.setDisabledFlags(mDisabledFlags1);
mNavigationBarView.setOnVerticalChangedListener(this::onVerticalChanged);
mNavigationBarView.setOnTouchListener(this::onNavigationTouch);
- if (savedInstanceState != null) {
- mNavigationBarView.getLightTransitionsController().restoreState(savedInstanceState);
+ if (mSavedState != null) {
+ mNavigationBarView.getLightTransitionsController().restoreState(mSavedState);
}
mNavigationBarView.setNavigationIconHints(mNavigationIconHints);
mNavigationBarView.setWindowVisible(isNavBarWindowVisible());
@@ -561,11 +564,32 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
initSecondaryHomeHandleForRotation();
+
+ // Unfortunately, we still need it because status bar needs LightBarController
+ // before notifications creation. We cannot directly use getLightBarController()
+ // from NavigationBarFragment directly.
+ LightBarController lightBarController = mIsOnDefaultDisplay
+ ? Dependency.get(LightBarController.class)
+ : new LightBarController(mContext,
+ Dependency.get(DarkIconDispatcher.class),
+ Dependency.get(BatteryController.class),
+ Dependency.get(NavigationModeController.class));
+ setLightBarController(lightBarController);
+
+ // TODO(b/118592525): to support multi-display, we start to add something which is
+ // per-display, while others may be global. I think it's time to
+ // add a new class maybe named DisplayDependency to solve
+ // per-display Dependency problem.
+ AutoHideController autoHideController = mIsOnDefaultDisplay
+ ? Dependency.get(AutoHideController.class)
+ : new AutoHideController(mContext, mHandler,
+ Dependency.get(IWindowManager.class));
+ setAutoHideController(autoHideController);
+ restoreAppearanceAndTransientState();
}
@Override
- public void onDestroyView() {
- super.onDestroyView();
+ public void onViewDetachedFromWindow(View v) {
if (mNavigationBarView != null) {
if (mIsOnDefaultDisplay) {
mNavigationBarView.getBarTransitions()
@@ -573,13 +597,13 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
mAssistHandlerViewController = null;
}
mNavigationBarView.getBarTransitions().destroy();
- mNavigationBarView.getLightTransitionsController().destroy(getContext());
+ mNavigationBarView.getLightTransitionsController().destroy(mContext);
}
mOverviewProxyService.removeCallback(mOverviewProxyListener);
mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
if (mOrientationHandle != null) {
resetSecondaryHandle();
- getContext().getSystemService(DisplayManager.class).unregisterDisplayListener(this);
+ mContext.getSystemService(DisplayManager.class).unregisterDisplayListener(this);
getBarTransitions().removeDarkIntensityListener(mOrientationHandleIntensityListener);
mWindowManager.removeView(mOrientationHandle);
mOrientationHandle.getViewTreeObserver().removeOnGlobalLayoutListener(
@@ -590,9 +614,8 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
mOrientationHandle = null;
}
- @Override
+ // TODO: Remove this when we update nav bar recreation
public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
outState.putInt(EXTRA_DISABLE_STATE, mDisabledFlags1);
outState.putInt(EXTRA_DISABLE2_STATE, mDisabledFlags2);
outState.putInt(EXTRA_APPEARANCE, mAppearance);
@@ -602,10 +625,11 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
}
- @Override
+ /**
+ * Called when a non-reloading configuration change happens and we need to update.
+ */
public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- final Locale locale = getContext().getResources().getConfiguration().locale;
+ final Locale locale = mContext.getResources().getConfiguration().locale;
final int ld = TextUtils.getLayoutDirectionFromLocale(locale);
if (!locale.equals(mLocale) || ld != mLayoutDirection) {
if (DEBUG) {
@@ -625,10 +649,10 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
return;
}
- getContext().getSystemService(DisplayManager.class)
+ mContext.getSystemService(DisplayManager.class)
.registerDisplayListener(this, new Handler(Looper.getMainLooper()));
- mOrientationHandle = new QuickswitchOrientedNavHandle(getContext());
+ mOrientationHandle = new QuickswitchOrientedNavHandle(mContext);
mOrientationHandle.setId(R.id.secondary_home_handle);
getBarTransitions().addDarkIntensityListener(mOrientationHandleIntensityListener);
@@ -640,7 +664,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_SLIPPERY,
PixelFormat.TRANSLUCENT);
- mOrientationParams.setTitle("SecondaryHomeHandle" + getContext().getDisplayId());
+ mOrientationParams.setTitle("SecondaryHomeHandle" + mContext.getDisplayId());
mOrientationParams.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
mWindowManager.addView(mOrientationHandle, mOrientationParams);
mOrientationHandle.setVisibility(View.GONE);
@@ -729,23 +753,20 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
return delta;
}
- @Override
- public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args) {
+ public void dump(PrintWriter pw) {
+ pw.println("NavigationBar (displayId=" + mDisplayId + "):");
+ pw.println(" mStartingQuickSwitchRotation=" + mStartingQuickSwitchRotation);
+ pw.println(" mCurrentRotation=" + mCurrentRotation);
+
if (mNavigationBarView != null) {
- pw.print(" mNavigationBarWindowState=");
- pw.println(windowStateToString(mNavigationBarWindowState));
- pw.print(" mNavigationBarMode=");
- pw.println(BarTransitions.modeToString(mNavigationBarMode));
+ pw.println(" mNavigationBarWindowState="
+ + windowStateToString(mNavigationBarWindowState));
+ pw.println(" mNavigationBarMode="
+ + BarTransitions.modeToString(mNavigationBarMode));
dumpBarTransitions(pw, "mNavigationBarView", mNavigationBarView.getBarTransitions());
- }
-
- pw.print(" mStartingQuickSwitchRotation=" + mStartingQuickSwitchRotation);
- pw.print(" mCurrentRotation=" + mCurrentRotation);
- pw.print(" mNavigationBarView=");
- if (mNavigationBarView == null) {
- pw.println("null");
+ mNavigationBarView.dump(pw);
} else {
- mNavigationBarView.dump(fd, pw, args);
+ pw.print(" mNavigationBarView=null");
}
}
@@ -834,15 +855,18 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
rotationButtonController.onRotationProposal(rotation, winRotation, isValid);
}
- /** Restores the appearance and the transient saved state to {@link NavigationBarFragment}. */
+ /** Restores the appearance and the transient saved state to {@link NavigationBar}. */
public void restoreAppearanceAndTransientState() {
final int barMode = barMode(mTransientShown, mAppearance);
mNavigationBarMode = barMode;
checkNavBarModes();
- mAutoHideController.touchAutoHide();
-
- mLightBarController.onNavigationBarAppearanceChanged(mAppearance, true /* nbModeChanged */,
- barMode, false /* navbarColorManagedByIme */);
+ if (mAutoHideController != null) {
+ mAutoHideController.touchAutoHide();
+ }
+ if (mLightBarController != null) {
+ mLightBarController.onNavigationBarAppearanceChanged(mAppearance,
+ true /* nbModeChanged */, barMode, false /* navbarColorManagedByIme */);
+ }
}
@Override
@@ -859,8 +883,10 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
nbModeChanged = updateBarMode(barMode(mTransientShown, appearance));
}
- mLightBarController.onNavigationBarAppearanceChanged(appearance, nbModeChanged,
- mNavigationBarMode, navbarColorManagedByIme);
+ if (mLightBarController != null) {
+ mLightBarController.onNavigationBarAppearanceChanged(appearance, nbModeChanged,
+ mNavigationBarMode, navbarColorManagedByIme);
+ }
}
@Override
@@ -903,7 +929,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
mNavigationBarView.onTransientStateChanged(mTransientShown);
}
final int barMode = barMode(mTransientShown, mAppearance);
- if (updateBarMode(barMode)) {
+ if (updateBarMode(barMode) && mLightBarController != null) {
mLightBarController.onNavigationBarModeChanged(barMode);
}
}
@@ -917,7 +943,9 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
mNavigationBarMode = barMode;
checkNavBarModes();
- mAutoHideController.touchAutoHide();
+ if (mAutoHideController != null) {
+ mAutoHideController.touchAutoHide();
+ }
return true;
}
return false;
@@ -1053,7 +1081,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
case MotionEvent.ACTION_DOWN:
mHomeBlockedThisTouch = false;
TelecomManager telecomManager =
- getContext().getSystemService(TelecomManager.class);
+ mContext.getSystemService(TelecomManager.class);
if (telecomManager != null && telecomManager.isRinging()) {
if (mStatusBarLazy.get().isKeyguardShowing()) {
Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
@@ -1076,7 +1104,9 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
private boolean onNavigationTouch(View v, MotionEvent event) {
- mAutoHideController.checkUserAutoHide(event);
+ if (mAutoHideController != null) {
+ mAutoHideController.checkUserAutoHide(event);
+ }
return false;
}
@@ -1094,7 +1124,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
Bundle args = new Bundle();
args.putInt(
AssistManager.INVOCATION_TYPE_KEY, AssistManager.INVOCATION_HOME_BUTTON_LONG_PRESS);
- mAssistManager.startAssist(args);
+ mAssistManagerLazy.get().startAssist(args);
mStatusBarLazy.get().awakenDreams();
if (mNavigationBarView != null) {
@@ -1120,8 +1150,8 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
private void onRecentsClick(View v) {
- if (LatencyTracker.isEnabled(getContext())) {
- LatencyTracker.getInstance(getContext()).onActionStart(
+ if (LatencyTracker.isEnabled(mContext)) {
+ LatencyTracker.getInstance(mContext).onActionStart(
LatencyTracker.ACTION_TOGGLE_RECENTS);
}
mStatusBarLazy.get().awakenDreams();
@@ -1215,7 +1245,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
private boolean onLongPressRecents() {
- if (mRecentsOptional.isPresent() || !ActivityTaskManager.supportsMultiWindow(getContext())
+ if (mRecentsOptional.isPresent() || !ActivityTaskManager.supportsMultiWindow(mContext)
|| !mDivider.getView().getSnapAlgorithm().isSplitScreenFeasible()
|| ActivityManager.isLowRamDeviceStatic()
// If we are connected to the overview service, then disable the recents button
@@ -1230,7 +1260,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
private void onAccessibilityClick(View v) {
final Display display = v.getDisplay();
mAccessibilityManager.notifyAccessibilityButtonClicked(
- display != null ? display.getDisplayId() : Display.DEFAULT_DISPLAY);
+ display != null ? display.getDisplayId() : DEFAULT_DISPLAY);
}
private boolean onAccessibilityLongClick(View v) {
@@ -1238,7 +1268,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
final String chooserClassName = AccessibilityButtonChooserActivity.class.getName();
intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
- v.getContext().startActivityAsUser(intent, UserHandle.CURRENT);
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT);
return true;
}
@@ -1335,7 +1365,10 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
public void setLightBarController(LightBarController lightBarController) {
mLightBarController = lightBarController;
- mLightBarController.setNavigationBar(mNavigationBarView.getLightTransitionsController());
+ if (mLightBarController != null) {
+ mLightBarController.setNavigationBar(
+ mNavigationBarView.getLightTransitionsController());
+ }
}
/** Sets {@link AutoHideController} to the navigation bar. */
@@ -1381,17 +1414,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
if (!canShowSecondaryHandle()) {
resetSecondaryHandle();
}
-
- // Workaround for b/132825155, for secondary users, we currently don't receive configuration
- // changes on overlay package change since SystemUI runs for the system user. In this case,
- // trigger a new configuration change to ensure that the nav bar is updated in the same way.
- int userId = ActivityManagerWrapper.getInstance().getCurrentUserId();
- if (userId != UserHandle.USER_SYSTEM) {
- mHandler.post(() -> {
- FragmentHostManager fragmentHost = FragmentHostManager.get(mNavigationBarView);
- fragmentHost.reloadFragments();
- });
- }
}
public void disableAnimationsDuringHide(long delay) {
@@ -1442,7 +1464,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
return;
}
- int rotation = getContext().getResources().getConfiguration()
+ int rotation = mContext.getResources().getConfiguration()
.windowConfiguration.getRotation();
if (rotation != mCurrentRotation) {
mCurrentRotation = rotation;
@@ -1480,37 +1502,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
}
};
- public static View create(Context context, FragmentListener listener) {
- WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
- WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
- | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
- | WindowManager.LayoutParams.FLAG_SLIPPERY,
- PixelFormat.TRANSLUCENT);
- lp.token = new Binder();
- lp.setTitle("NavigationBar" + context.getDisplayId());
- lp.accessibilityTitle = context.getString(R.string.nav_bar);
- lp.windowAnimations = 0;
- lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
-
- View navigationBarView = LayoutInflater.from(context).inflate(
- R.layout.navigation_bar_window, null);
-
- if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + navigationBarView);
- if (navigationBarView == null) return null;
-
- NavigationBarFragment fragment = FragmentHostManager.get(navigationBarView)
- .create(NavigationBarFragment.class);
- navigationBarView.addOnAttachStateChangeListener(new NavBarViewAttachedListener(fragment,
- listener));
- context.getSystemService(WindowManager.class).addView(navigationBarView, lp);
- return navigationBarView;
- }
-
@VisibleForTesting
int getNavigationIconHints() {
return mNavigationIconHints;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
new file mode 100644
index 000000000000..73cdde8a0c91
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.navigationbar;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.hardware.display.DisplayManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.Display;
+import android.view.IWindowManager;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.view.accessibility.AccessibilityManager;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.statusbar.RegisterStatusBarResult;
+import com.android.settingslib.applications.InterestingConfigChanges;
+import com.android.systemui.Dumpable;
+import com.android.systemui.accessibility.SystemActions;
+import com.android.systemui.assist.AssistHandleViewController;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.CommandQueue.Callbacks;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+
+
+/** A controller to handle navigation bars. */
+@Singleton
+public class NavigationBarController implements Callbacks,
+ ConfigurationController.ConfigurationListener,
+ NavigationModeController.ModeChangedListener, Dumpable {
+
+ private static final String TAG = NavigationBarController.class.getSimpleName();
+
+ private final Context mContext;
+ private final WindowManager mWindowManager;
+ private final Lazy<AssistManager> mAssistManagerLazy;
+ private final AccessibilityManager mAccessibilityManager;
+ private final AccessibilityManagerWrapper mAccessibilityManagerWrapper;
+ private final DeviceProvisionedController mDeviceProvisionedController;
+ private final MetricsLogger mMetricsLogger;
+ private final OverviewProxyService mOverviewProxyService;
+ private final NavigationModeController mNavigationModeController;
+ private final StatusBarStateController mStatusBarStateController;
+ private final SysUiState mSysUiFlagsContainer;
+ private final BroadcastDispatcher mBroadcastDispatcher;
+ private final CommandQueue mCommandQueue;
+ private final Divider mDivider;
+ private final Optional<Recents> mRecentsOptional;
+ private final Lazy<StatusBar> mStatusBarLazy;
+ private final ShadeController mShadeController;
+ private final NotificationRemoteInputManager mNotificationRemoteInputManager;
+ private final SystemActions mSystemActions;
+ private final UiEventLogger mUiEventLogger;
+ private final Handler mHandler;
+ private final DisplayManager mDisplayManager;
+
+ /** A displayId - nav bar maps. */
+ @VisibleForTesting
+ SparseArray<NavigationBar> mNavigationBars = new SparseArray<>();
+
+ // Tracks config changes that will actually recreate the nav bar
+ private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
+ ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
+ | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS
+ | ActivityInfo.CONFIG_UI_MODE);
+
+ @Inject
+ public NavigationBarController(Context context,
+ WindowManager windowManager,
+ Lazy<AssistManager> assistManagerLazy,
+ AccessibilityManager accessibilityManager,
+ AccessibilityManagerWrapper accessibilityManagerWrapper,
+ DeviceProvisionedController deviceProvisionedController,
+ MetricsLogger metricsLogger,
+ OverviewProxyService overviewProxyService,
+ NavigationModeController navigationModeController,
+ StatusBarStateController statusBarStateController,
+ SysUiState sysUiFlagsContainer,
+ BroadcastDispatcher broadcastDispatcher,
+ CommandQueue commandQueue,
+ Divider divider,
+ Optional<Recents> recentsOptional,
+ Lazy<StatusBar> statusBarLazy,
+ ShadeController shadeController,
+ NotificationRemoteInputManager notificationRemoteInputManager,
+ SystemActions systemActions,
+ @Main Handler mainHandler,
+ UiEventLogger uiEventLogger,
+ ConfigurationController configurationController) {
+ mContext = context;
+ mWindowManager = windowManager;
+ mAssistManagerLazy = assistManagerLazy;
+ mAccessibilityManager = accessibilityManager;
+ mAccessibilityManagerWrapper = accessibilityManagerWrapper;
+ mDeviceProvisionedController = deviceProvisionedController;
+ mMetricsLogger = metricsLogger;
+ mOverviewProxyService = overviewProxyService;
+ mNavigationModeController = navigationModeController;
+ mStatusBarStateController = statusBarStateController;
+ mSysUiFlagsContainer = sysUiFlagsContainer;
+ mBroadcastDispatcher = broadcastDispatcher;
+ mCommandQueue = commandQueue;
+ mDivider = divider;
+ mRecentsOptional = recentsOptional;
+ mStatusBarLazy = statusBarLazy;
+ mShadeController = shadeController;
+ mNotificationRemoteInputManager = notificationRemoteInputManager;
+ mSystemActions = systemActions;
+ mUiEventLogger = uiEventLogger;
+ mHandler = mainHandler;
+ mDisplayManager = mContext.getSystemService(DisplayManager.class);
+ commandQueue.addCallback(this);
+ configurationController.addCallback(this);
+ mConfigChanges.applyNewConfig(mContext.getResources());
+ }
+
+ @Override
+ public void onConfigChanged(Configuration newConfig) {
+ if (mConfigChanges.applyNewConfig(mContext.getResources())) {
+ for (int i = 0; i < mNavigationBars.size(); i++) {
+ recreateNavigationBar(mNavigationBars.keyAt(i));
+ }
+ } else {
+ for (int i = 0; i < mNavigationBars.size(); i++) {
+ mNavigationBars.get(i).onConfigurationChanged(newConfig);
+ }
+ }
+ }
+
+ @Override
+ public void onNavigationModeChanged(int mode) {
+ // Workaround for b/132825155, for secondary users, we currently don't receive configuration
+ // changes on overlay package change since SystemUI runs for the system user. In this case,
+ // trigger a new configuration change to ensure that the nav bar is updated in the same way.
+ int userId = ActivityManagerWrapper.getInstance().getCurrentUserId();
+ if (userId != UserHandle.USER_SYSTEM) {
+ mHandler.post(() -> {
+ for (int i = 0; i < mNavigationBars.size(); i++) {
+ recreateNavigationBar(mNavigationBars.keyAt(i));
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ removeNavigationBar(displayId);
+ }
+
+ @Override
+ public void onDisplayReady(int displayId) {
+ Display display = mDisplayManager.getDisplay(displayId);
+ createNavigationBar(display, null /* savedState */, null /* result */);
+ }
+
+ /**
+ * Recreates the navigation bar for the given display.
+ */
+ private void recreateNavigationBar(int displayId) {
+ // TODO: Improve this flow so that we don't need to create a new nav bar but just
+ // the view
+ Bundle savedState = new Bundle();
+ NavigationBar bar = mNavigationBars.get(displayId);
+ if (bar != null) {
+ bar.onSaveInstanceState(savedState);
+ }
+ removeNavigationBar(displayId);
+ createNavigationBar(mDisplayManager.getDisplay(displayId), savedState, null /* result */);
+ }
+
+ // TODO(b/117478341): I use {@code includeDefaultDisplay} to make this method compatible to
+ // CarStatusBar because they have their own nav bar. Think about a better way for it.
+ /**
+ * Creates navigation bars when car/status bar initializes.
+ *
+ * @param includeDefaultDisplay {@code true} to create navigation bar on default display.
+ */
+ public void createNavigationBars(final boolean includeDefaultDisplay,
+ RegisterStatusBarResult result) {
+ Display[] displays = mDisplayManager.getDisplays();
+ for (Display display : displays) {
+ if (includeDefaultDisplay || display.getDisplayId() != DEFAULT_DISPLAY) {
+ createNavigationBar(display, null /* savedState */, result);
+ }
+ }
+ }
+
+ /**
+ * Adds a navigation bar on default display or an external display if the display supports
+ * system decorations.
+ *
+ * @param display the display to add navigation bar on.
+ */
+ @VisibleForTesting
+ void createNavigationBar(Display display, Bundle savedState, RegisterStatusBarResult result) {
+ if (display == null) {
+ return;
+ }
+
+ final int displayId = display.getDisplayId();
+ final boolean isOnDefaultDisplay = displayId == DEFAULT_DISPLAY;
+ final IWindowManager wms = WindowManagerGlobal.getWindowManagerService();
+
+ try {
+ if (!wms.hasNavigationBar(displayId)) {
+ return;
+ }
+ } catch (RemoteException e) {
+ // Cannot get wms, just return with warning message.
+ Log.w(TAG, "Cannot get WindowManager.");
+ return;
+ }
+ final Context context = isOnDefaultDisplay
+ ? mContext
+ : mContext.createDisplayContext(display);
+ NavigationBar navBar = new NavigationBar(context,
+ mWindowManager,
+ mAssistManagerLazy,
+ mAccessibilityManager,
+ mAccessibilityManagerWrapper,
+ mDeviceProvisionedController,
+ mMetricsLogger,
+ mOverviewProxyService,
+ mNavigationModeController,
+ mStatusBarStateController,
+ mSysUiFlagsContainer,
+ mBroadcastDispatcher,
+ mCommandQueue,
+ mDivider,
+ mRecentsOptional,
+ mStatusBarLazy,
+ mShadeController,
+ mNotificationRemoteInputManager,
+ mSystemActions,
+ mHandler,
+ mUiEventLogger);
+
+ View navigationBarView = navBar.createView(savedState);
+ navigationBarView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ mNavigationBars.put(displayId, navBar);
+
+ if (result != null) {
+ navBar.setImeWindowStatus(display.getDisplayId(), result.mImeToken,
+ result.mImeWindowVis, result.mImeBackDisposition,
+ result.mShowImeSwitcher);
+ }
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ v.removeOnAttachStateChangeListener(this);
+ }
+ });
+ }
+
+ private void removeNavigationBar(int displayId) {
+ NavigationBar navBar = mNavigationBars.get(displayId);
+ if (navBar != null) {
+ navBar.setAutoHideController(/* autoHideController */ null);
+ navBar.destroyView();
+ mNavigationBars.remove(displayId);
+ }
+ }
+
+ /** @see NavigationBar#checkNavBarModes() */
+ public void checkNavBarModes(int displayId) {
+ NavigationBar navBar = mNavigationBars.get(displayId);
+ if (navBar != null) {
+ navBar.checkNavBarModes();
+ }
+ }
+
+ /** @see NavigationBar#finishBarAnimations() */
+ public void finishBarAnimations(int displayId) {
+ NavigationBar navBar = mNavigationBars.get(displayId);
+ if (navBar != null) {
+ navBar.finishBarAnimations();
+ }
+ }
+
+ /** @see NavigationBar#touchAutoDim() */
+ public void touchAutoDim(int displayId) {
+ NavigationBar navBar = mNavigationBars.get(displayId);
+ if (navBar != null) {
+ navBar.touchAutoDim();
+ }
+ }
+
+ /** @see NavigationBar#transitionTo(int, boolean) */
+ public void transitionTo(int displayId, @TransitionMode int barMode, boolean animate) {
+ NavigationBar navBar = mNavigationBars.get(displayId);
+ if (navBar != null) {
+ navBar.transitionTo(barMode, animate);
+ }
+ }
+
+ /** @see NavigationBar#disableAnimationsDuringHide(long) */
+ public void disableAnimationsDuringHide(int displayId, long delay) {
+ NavigationBar navBar = mNavigationBars.get(displayId);
+ if (navBar != null) {
+ navBar.disableAnimationsDuringHide(delay);
+ }
+ }
+
+ /** @return {@link NavigationBarView} on the default display. */
+ public @Nullable NavigationBarView getDefaultNavigationBarView() {
+ return getNavigationBarView(DEFAULT_DISPLAY);
+ }
+
+ /**
+ * @param displayId the ID of display which Navigation bar is on
+ * @return {@link NavigationBarView} on the display with {@code displayId}.
+ * {@code null} if no navigation bar on that display.
+ */
+ public @Nullable NavigationBarView getNavigationBarView(int displayId) {
+ NavigationBar navBar = mNavigationBars.get(displayId);
+ return (navBar == null) ? null : (NavigationBarView) navBar.getView();
+ }
+
+ /** @return {@link NavigationBar} on the default display. */
+ @Nullable
+ public NavigationBar getDefaultNavigationBar() {
+ return mNavigationBars.get(DEFAULT_DISPLAY);
+ }
+
+ /** @return {@link AssistHandleViewController} (only on the default display). */
+ @Nullable
+ public AssistHandleViewController getAssistHandlerViewController() {
+ NavigationBar navBar = getDefaultNavigationBar();
+ return navBar == null ? null : navBar.getAssistHandlerViewController();
+ }
+
+ @Override
+ public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
+ for (int i = 0; i < mNavigationBars.size(); i++) {
+ if (i > 0) {
+ pw.println();
+ }
+ mNavigationBars.get(i).dump(pw);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java
index 741f7839f455..6c531d8233f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFrame.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java
@@ -1,18 +1,20 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static android.view.MotionEvent.ACTION_OUTSIDE;
@@ -24,7 +26,7 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;
-import com.android.systemui.statusbar.policy.DeadZone;
+import com.android.systemui.navigationbar.buttons.DeadZone;
public class NavigationBarFrame extends FrameLayout {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
index 4337e20c0a39..27074606d251 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
@@ -1,18 +1,20 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
@@ -35,10 +37,12 @@ import android.widget.Space;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.buttons.ReverseLinearLayout;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseRelativeLayout;
-import com.android.systemui.statusbar.policy.KeyButtonView;
+import com.android.systemui.navigationbar.buttons.ReverseLinearLayout.ReverseRelativeLayout;
import java.io.PrintWriter;
import java.util.Objects;
@@ -472,8 +476,7 @@ public class NavigationBarInflaterView extends FrameLayout
}
public void dump(PrintWriter pw) {
- pw.println("NavigationBarInflaterView {");
- pw.println(" mCurrentLayout: " + mCurrentLayout);
- pw.println(" }");
+ pw.println("NavigationBarInflaterView");
+ pw.println(" mCurrentLayout: " + mCurrentLayout);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
index 1f509549efd1..c0535b5fc77b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,27 +14,27 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay;
-import android.content.Context;
import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.util.SparseArray;
import android.view.Display;
import android.view.IWallpaperVisibilityListener;
import android.view.IWindowManager;
import android.view.View;
-import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.phone.LightBarTransitionsController;
import java.util.ArrayList;
import java.util.List;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index e3cb105ba2f7..a3351838ecf2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
@@ -70,6 +70,15 @@ import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.assist.AssistHandleViewController;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.buttons.ContextualButton;
+import com.android.systemui.navigationbar.buttons.ContextualButtonGroup;
+import com.android.systemui.navigationbar.buttons.DeadZone;
+import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
+import com.android.systemui.navigationbar.buttons.RotationContextButton;
+import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.navigationbar.gestural.FloatingRotationButton;
+import com.android.systemui.navigationbar.gestural.RegionSamplingHelper;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsOnboarding;
@@ -80,9 +89,10 @@ import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.NavigationBarController;
-import com.android.systemui.statusbar.policy.DeadZone;
-import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.LightBarTransitionsController;
+import com.android.systemui.statusbar.phone.NotificationPanelViewController;
+import com.android.systemui.statusbar.phone.StatusBar;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -167,7 +177,7 @@ public class NavigationBarView extends FrameLayout implements
* When quickswitching between apps of different orientations, we draw a secondary home handle
* in the position of the first app's orientation. This rect represents the region of that
* home handle so we can apply the correct light/dark luma on that.
- * @see {@link NavigationBarFragment#mOrientationHandle}
+ * @see {@link NavigationBar#mOrientationHandle}
*/
@Nullable
private Rect mOrientedHandleSamplingRegion;
@@ -779,7 +789,7 @@ public class NavigationBarView extends FrameLayout implements
} else {
return;
}
- WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
+ WindowManager wm = getContext().getSystemService(WindowManager.class);
wm.updateViewLayout((View) getParent(), lp);
}
}
@@ -867,7 +877,7 @@ public class NavigationBarView extends FrameLayout implements
} else {
lp.flags &= ~flags;
}
- WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+ WindowManager wm = getContext().getSystemService(WindowManager.class);
wm.updateViewLayout(navbarView, lp);
}
@@ -1163,6 +1173,9 @@ public class NavigationBarView extends FrameLayout implements
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+ // This needs to happen first as it can changed the enabled state which can affect whether
+ // the back button is visible
+ mEdgeBackGestureHandler.onNavBarAttached();
requestApplyInsets();
reorient();
onNavigationModeChanged(mNavBarMode);
@@ -1171,7 +1184,6 @@ public class NavigationBarView extends FrameLayout implements
mRotationButtonController.registerListeners();
}
- mEdgeBackGestureHandler.onNavBarAttached();
getViewTreeObserver().addOnComputeInternalInsetsListener(mOnComputeInternalInsetsListener);
}
@@ -1200,12 +1212,12 @@ public class NavigationBarView extends FrameLayout implements
}
}
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("NavigationBarView {");
+ public void dump(PrintWriter pw) {
final Rect r = new Rect();
final Point size = new Point();
getContextDisplay().getRealSize(size);
+ pw.println("NavigationBarView:");
pw.println(String.format(" this: " + StatusBar.viewInfo(this)
+ " " + visibilityToString(getVisibility())));
@@ -1228,6 +1240,8 @@ public class NavigationBarView extends FrameLayout implements
getLightTransitionsController().getCurrentDarkIntensity()));
pw.println(" mOrientedHandleSamplingRegion: " + mOrientedHandleSamplingRegion);
+ pw.println(" mScreenOn: " + mScreenOn);
+
dumpButton(pw, "back", getBackButton());
dumpButton(pw, "home", getHomeButton());
@@ -1236,9 +1250,6 @@ public class NavigationBarView extends FrameLayout implements
dumpButton(pw, "a11y", getAccessibilityButton());
dumpButton(pw, "ime", getImeSwitchButton());
- pw.println(" }");
- pw.println(" mScreenOn: " + mScreenOn);
-
if (mNavigationInflaterView != null) {
mNavigationInflaterView.dump(pw);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationModeController.java
index c211de08cb8e..6e301c915af7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationModeController.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static android.content.Intent.ACTION_OVERLAY_CHANGED;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java b/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButton.java
index 74d4eb175ac4..e48785844347 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButton.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import android.view.View;
-import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
import java.util.function.Consumer;
/** Interface of a rotation button that interacts {@link RotationButtonController}. */
-interface RotationButton {
+public interface RotationButton {
void setRotationButtonController(RotationButtonController rotationButtonController);
void setVisibilityChangedCallback(Consumer<Boolean> visibilityChangedCallback);
View getCurrentView();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java
index 2f2e1f9a1f2e..6cbf065ea6a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationButtonController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/RotationButtonController.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static com.android.internal.view.RotationPolicy.NATURAL_ROTATION;
@@ -23,7 +23,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
-import android.annotation.StyleRes;
import android.app.StatusBarManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -32,7 +31,6 @@ import android.os.Looper;
import android.os.RemoteException;
import android.provider.Settings;
import android.util.Log;
-import android.view.ContextThemeWrapper;
import android.view.IRotationWatcher.Stub;
import android.view.MotionEvent;
import android.view.Surface;
@@ -43,14 +41,13 @@ import android.view.accessibility.AccessibilityManager;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
-import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
-import com.android.systemui.statusbar.policy.KeyButtonDrawable;
import com.android.systemui.statusbar.policy.RotationLockController;
import java.util.Optional;
@@ -328,7 +325,7 @@ public class RotationButtonController {
}
}
- Context getContext() {
+ public Context getContext() {
return mContext;
}
@@ -336,15 +333,15 @@ public class RotationButtonController {
return mRotationButton;
}
- @DrawableRes int getIconResId() {
+ public @DrawableRes int getIconResId() {
return mIconResId;
}
- @ColorInt int getLightIconColor() {
+ public @ColorInt int getLightIconColor() {
return mLightIconColor;
}
- @ColorInt int getDarkIconColor() {
+ public @ColorInt int getDarkIconColor() {
return mDarkIconColor;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java b/packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java
index 071e00d08d67..ac7baf592599 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/ScreenPinningNotify.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import android.content.Context;
import android.os.SystemClock;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java
index c2731089132c..ade2923acdf6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java
@@ -1,18 +1,20 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.buttons;
import static com.android.systemui.Interpolators.LINEAR;
@@ -24,7 +26,6 @@ import android.view.View.AccessibilityDelegate;
import com.android.systemui.Dependency;
import com.android.systemui.assist.AssistManager;
-import com.android.systemui.statusbar.policy.KeyButtonDrawable;
import java.util.ArrayList;
@@ -75,11 +76,11 @@ public class ButtonDispatcher {
mAssistManager = Dependency.get(AssistManager.class);
}
- void clear() {
+ public void clear() {
mViews.clear();
}
- void addView(View view) {
+ public void addView(View view) {
mViews.add(view);
view.setOnClickListener(mClickListener);
view.setOnTouchListener(mTouchListener);
@@ -337,6 +338,6 @@ public class ButtonDispatcher {
/**
* Executes when button is detached from window.
*/
- protected void onDestroy() {
+ public void onDestroy() {
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonInterface.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java
index 150a9603a124..8d291ddf5f19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonInterface.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.buttons;
import android.annotation.Nullable;
import android.graphics.drawable.Drawable;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java
index eb476457dcec..453e85ae25c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.buttons;
import android.annotation.DrawableRes;
import android.annotation.IdRes;
@@ -22,9 +22,6 @@ import android.annotation.NonNull;
import android.content.Context;
import android.view.View;
-import com.android.systemui.statusbar.policy.KeyButtonDrawable;
-import com.android.systemui.statusbar.policy.KeyButtonView;
-
/**
* Simple contextual button that is added to the {@link ContextualButtonGroup}. Extend if need extra
* functionality.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java
index c1017f4def0f..50b638bcc903 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.buttons;
import android.annotation.IdRes;
import android.annotation.NonNull;
@@ -119,21 +119,20 @@ public class ContextualButtonGroup extends ButtonDispatcher {
public void dump(PrintWriter pw) {
View view = getCurrentView();
- pw.println("ContextualButtonGroup {");
- pw.println(" getVisibleContextButton(): " + getVisibleContextButton());
- pw.println(" isVisible(): " + isVisible());
- pw.println(" attached(): " + (view != null && view.isAttachedToWindow()));
- pw.println(" mButtonData [ ");
+ pw.println("ContextualButtonGroup");
+ pw.println(" getVisibleContextButton(): " + getVisibleContextButton());
+ pw.println(" isVisible(): " + isVisible());
+ pw.println(" attached(): " + (view != null && view.isAttachedToWindow()));
+ pw.println(" mButtonData [ ");
for (int i = mButtonData.size() - 1; i >= 0; --i) {
final ButtonData data = mButtonData.get(i);
view = data.button.getCurrentView();
- pw.println(" " + i + ": markedVisible=" + data.markedVisible
+ pw.println(" " + i + ": markedVisible=" + data.markedVisible
+ " visible=" + data.button.getVisibility()
+ " attached=" + (view != null && view.isAttachedToWindow())
+ " alpha=" + data.button.getAlpha());
}
- pw.println(" ]");
- pw.println(" }");
+ pw.println(" ]");
}
private int getContextButtonIndex(@IdRes int buttonResId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java
index 12d0617d90ff..7e5b5548237b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.navigationbar.buttons;
import android.animation.ObjectAnimator;
import android.content.res.Resources;
@@ -26,8 +26,8 @@ import android.view.Surface;
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.statusbar.NavigationBarController;
-import com.android.systemui.statusbar.phone.NavigationBarView;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationBarView;
/**
* The "dead zone" consumes unintentional taps along the top edge of the navigation bar.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java
index 755938863b5e..fc2016913292 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.navigationbar.buttons;
import android.animation.ArgbEvaluator;
import android.annotation.ColorInt;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java
index 2d8784dc41bd..72cd4f1343e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonRipple.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.navigationbar.buttons;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java
index 8d7ecd09e760..d6b831640326 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.navigationbar.buttons;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.KeyEvent.KEYCODE_UNKNOWN;
@@ -61,7 +61,6 @@ import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.statusbar.phone.ButtonInterface;
public class KeyButtonView extends ImageView implements ButtonInterface {
private static final String TAG = KeyButtonView.class.getSimpleName();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java
index d02280836fb5..88c8fea085fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NearestTouchFrame.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java
@@ -1,18 +1,20 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.buttons;
import android.content.Context;
import android.content.res.Configuration;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java
index d3ec187ef20f..f1e1366404a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java
@@ -12,7 +12,7 @@
* permissions and limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.buttons;
import android.annotation.Nullable;
import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/RotationContextButton.java
index d63d445d8ba3..6a97a3379939 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/RotationContextButton.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,17 +11,20 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.buttons;
import android.annotation.DrawableRes;
import android.annotation.IdRes;
import android.content.Context;
import android.view.View;
-import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import com.android.systemui.navigationbar.RotationButton;
+import com.android.systemui.navigationbar.RotationButtonController;
+import com.android.systemui.navigationbar.buttons.ContextualButton;
+import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
import java.util.function.Consumer;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 9606318e1992..a1b55c428029 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -1,5 +1,5 @@
-/**
- * Copyright (C) 2019 The Android Open Source Project
+/*
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.gestural;
import static android.view.Display.INVALID_DISPLAY;
@@ -59,6 +59,8 @@ import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.NavigationEdgeBackPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.recents.OverviewProxyService;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/FloatingRotationButton.java
index 8a85f7d6a2c5..61118c5d26ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/FloatingRotationButton.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.gestural;
import android.content.Context;
import android.content.res.Resources;
@@ -27,8 +27,10 @@ import android.view.View;
import android.view.WindowManager;
import com.android.systemui.R;
-import com.android.systemui.statusbar.policy.KeyButtonDrawable;
-import com.android.systemui.statusbar.policy.KeyButtonView;
+import com.android.systemui.navigationbar.RotationButton;
+import com.android.systemui.navigationbar.RotationButtonController;
+import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
+import com.android.systemui.navigationbar.buttons.KeyButtonView;
import java.util.function.Consumer;
@@ -49,7 +51,7 @@ public class FloatingRotationButton implements RotationButton {
private RotationButtonController mRotationButtonController;
private Consumer<Boolean> mVisibilityChangedCallback;
- FloatingRotationButton(Context context) {
+ public FloatingRotationButton(Context context) {
mContext = context;
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mKeyButtonView = (KeyButtonView) LayoutInflater.from(mContext).inflate(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
index 23573095e037..284f41a416d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.gestural;
import android.animation.ValueAnimator;
import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
index b87479505d00..33e6aa46724b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.gestural;
import android.animation.ArgbEvaluator;
import android.annotation.ColorInt;
@@ -29,6 +29,7 @@ import android.view.View;
import com.android.settingslib.Utils;
import com.android.systemui.R;
+import com.android.systemui.navigationbar.buttons.ButtonInterface;
public class NavigationHandle extends View implements ButtonInterface {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickswitchOrientedNavHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java
index fe74677a8d51..71c8a2c1e6ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickswitchOrientedNavHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/QuickswitchOrientedNavHandle.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.gestural;
import android.content.Context;
import android.graphics.Canvas;
@@ -34,7 +34,7 @@ public class QuickswitchOrientedNavHandle extends NavigationHandle {
mWidth = context.getResources().getDimensionPixelSize(R.dimen.navigation_home_handle_width);
}
- void setDeltaRotation(@Surface.Rotation int rotation) {
+ public void setDeltaRotation(@Surface.Rotation int rotation) {
mDeltaRotation = rotation;
}
@@ -43,7 +43,7 @@ public class QuickswitchOrientedNavHandle extends NavigationHandle {
canvas.drawRoundRect(computeHomeHandleBounds(), mRadius, mRadius, mPaint);
}
- RectF computeHomeHandleBounds() {
+ public RectF computeHomeHandleBounds() {
int left;
int top;
int bottom;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/RegionSamplingHelper.java
index 3c8aa86dd209..70117eb6d2f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/RegionSamplingHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.gestural;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -108,7 +108,7 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener,
}
}
- void start(Rect initialSamplingBounds) {
+ public void start(Rect initialSamplingBounds) {
if (!mCallback.isSamplingEnabled()) {
return;
}
@@ -122,12 +122,12 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener,
updateSamplingListener();
}
- void stop() {
+ public void stop() {
mSamplingEnabled = false;
updateSamplingListener();
}
- void stopAndDestroy() {
+ public void stopAndDestroy() {
stop();
mSamplingListener.destroy();
mIsDestroyed = true;
@@ -220,12 +220,12 @@ public class RegionSamplingHelper implements View.OnAttachStateChangeListener,
}
}
- void setWindowVisible(boolean visible) {
+ public void setWindowVisible(boolean visible) {
mWindowVisible = visible;
updateSamplingListener();
}
- void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw) {
pw.println("RegionSamplingHelper:");
pw.println(" sampleView isAttached: " + mSampledView.isAttachedToWindow());
pw.println(" sampleView isScValid: " + (mSampledView.isAttachedToWindow()
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
index 8550959aa2c4..2e91697de849 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -26,6 +26,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
+import android.os.SystemProperties;
import android.util.Log;
import android.view.SurfaceControl;
import android.window.DisplayAreaInfo;
@@ -61,6 +62,8 @@ import javax.inject.Inject;
*/
public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer implements Dumpable {
private static final String TAG = "OneHandedDisplayAreaOrganizer";
+ private static final String ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION =
+ "persist.debug.one_handed_translate_animation_duration";
@VisibleForTesting
static final int MSG_RESET_IMMEDIATE = 1;
@@ -156,8 +159,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer implemen
mDisplayController = displayController;
mDefaultDisplayBounds.set(getDisplayBounds());
mLastVisualDisplayBounds.set(getDisplayBounds());
- mEnterExitAnimationDurationMs = context.getResources().getInteger(
- com.android.systemui.R.integer.config_one_handed_translate_animation_duration);
+ mEnterExitAnimationDurationMs =
+ SystemProperties.getInt(ONE_HANDED_MODE_TRANSLATE_ANIMATION_DURATION, 300);
mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
mTutorialHandler = tutorialHandler;
}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
index 563684ad65c1..ba50db1c9f72 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedGestureHandler.java
@@ -40,7 +40,7 @@ import android.window.WindowContainerTransaction;
import androidx.annotation.VisibleForTesting;
import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.wm.shell.common.DisplayChangeController;
import com.android.wm.shell.common.DisplayController;
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java
index a3921ee54fec..42524bb33818 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedManagerImpl.java
@@ -24,13 +24,13 @@ import android.content.ComponentName;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
+import android.os.SystemProperties;
import android.view.KeyEvent;
import androidx.annotation.NonNull;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dumpable;
-import com.android.systemui.R;
import com.android.systemui.model.SysUiState;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -50,6 +50,8 @@ import javax.inject.Singleton;
@Singleton
public class OneHandedManagerImpl implements OneHandedManager, Dumpable {
private static final String TAG = "OneHandedManager";
+ private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE =
+ "persist.debug.one_handed_offset_percentage";
private boolean mIsOneHandedEnabled;
private boolean mIsSwipeToNotificationEnabled;
@@ -117,8 +119,8 @@ public class OneHandedManagerImpl implements OneHandedManager, Dumpable {
mDisplayController = displayController;
mDisplayController.addDisplayChangingController(mRotationController);
mSysUiFlagContainer = sysUiState;
- mOffSetFraction =
- context.getResources().getFraction(R.fraction.config_one_handed_offset, 1, 1);
+ mOffSetFraction = SystemProperties.getInt(ONE_HANDED_MODE_OFFSET_PERCENTAGE, 50) / 100.0f;
+
mIsOneHandedEnabled = OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
context.getContentResolver());
mIsSwipeToNotificationEnabled = OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSettingsUtil.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSettingsUtil.java
index 1b6ec04193f0..279bbc862ff0 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSettingsUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedSettingsUtil.java
@@ -22,19 +22,13 @@ import android.database.ContentObserver;
import android.net.Uri;
import android.provider.Settings;
-import com.android.internal.annotations.VisibleForTesting;
-
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
/**
* APIs for querying or updating one handed settings .
*/
-@Singleton
public final class OneHandedSettingsUtil {
private static final String TAG = "OneHandedSettingsUtil";
@@ -65,11 +59,6 @@ public final class OneHandedSettingsUtil {
*/
public static final int ONE_HANDED_TIMEOUT_LONG_IN_SECONDS = 12;
- @VisibleForTesting
- @Inject
- OneHandedSettingsUtil() {
- }
-
/**
* Register one handed preference settings observer
*
@@ -150,4 +139,6 @@ public final class OneHandedSettingsUtil {
pw.print(innerPrefix + "tapsAppToExit=");
pw.println(getSettingsTapsAppToExit(resolver));
}
+
+ private OneHandedSettingsUtil() {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java
index b28730d004f6..de34b2ec831d 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedTutorialHandler.java
@@ -22,6 +22,7 @@ import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
+import android.os.SystemProperties;
import android.provider.Settings;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -50,6 +51,8 @@ import javax.inject.Singleton;
@Singleton
public class OneHandedTutorialHandler implements OneHandedTransitionCallback, Dumpable {
private static final String TAG = "OneHandedTutorialHandler";
+ private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE =
+ "persist.debug.one_handed_offset_percentage";
private static final int MAX_TUTORIAL_SHOW_COUNT = 2;
private final Rect mLastUpdatedBounds = new Rect();
private final WindowManager mWindowManager;
@@ -81,8 +84,8 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback, Du
mWindowManager = context.getSystemService(WindowManager.class);
mTargetViewContainer = new FrameLayout(context);
mTargetViewContainer.setClipChildren(false);
- mTutorialAreaHeight = Math.round(mDisplaySize.y * context.getResources().getFraction(
- R.fraction.config_one_handed_offset, 1, 1));
+ mTutorialAreaHeight = Math.round(mDisplaySize.y
+ * (SystemProperties.getInt(ONE_HANDED_MODE_OFFSET_PERCENTAGE, 50) / 100.0f));
mTutorialView = LayoutInflater.from(context).inflate(R.xml.one_handed_tutorial, null);
mTargetViewContainer.addView(mTutorialView);
mCanShowTutorial = (Settings.Secure.getInt(mContentResolver,
diff --git a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedUI.java b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedUI.java
index 0903c0e5c512..2767a8d18db4 100644
--- a/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedUI.java
+++ b/packages/SystemUI/src/com/android/systemui/onehanded/OneHandedUI.java
@@ -63,7 +63,6 @@ public class OneHandedUI extends SystemUI implements CommandQueue.Callbacks, Dum
private final CommandQueue mCommandQueue;
private final Handler mMainHandler = new Handler(Looper.getMainLooper());
private final IOverlayManager mOverlayManager;
- private final OneHandedSettingsUtil mSettingUtil;
private final OneHandedTimeoutHandler mTimeoutHandler;
private final ScreenLifecycle mScreenLifecycle;
@@ -154,7 +153,6 @@ public class OneHandedUI extends SystemUI implements CommandQueue.Callbacks, Dum
public OneHandedUI(Context context,
CommandQueue commandQueue,
OneHandedManagerImpl oneHandedManager,
- OneHandedSettingsUtil settingsUtil,
ScreenLifecycle screenLifecycle) {
super(context);
@@ -163,7 +161,6 @@ public class OneHandedUI extends SystemUI implements CommandQueue.Callbacks, Dum
mCommandQueue = null;
mOneHandedManager = null;
mOverlayManager = null;
- mSettingUtil = null;
mTimeoutHandler = null;
mScreenLifecycle = null;
return;
@@ -171,7 +168,6 @@ public class OneHandedUI extends SystemUI implements CommandQueue.Callbacks, Dum
mCommandQueue = commandQueue;
mOneHandedManager = oneHandedManager;
- mSettingUtil = settingsUtil;
mTimeoutHandler = OneHandedTimeoutHandler.get();
mScreenLifecycle = screenLifecycle;
mOverlayManager = IOverlayManager.Stub.asInterface(
@@ -252,26 +248,26 @@ public class OneHandedUI extends SystemUI implements CommandQueue.Callbacks, Dum
}
private void setupSettingObservers() {
- mSettingUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_ENABLED,
+ OneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_ENABLED,
mContext.getContentResolver(), mEnabledObserver);
- mSettingUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_TIMEOUT,
+ OneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.ONE_HANDED_MODE_TIMEOUT,
mContext.getContentResolver(), mTimeoutObserver);
- mSettingUtil.registerSettingsKeyObserver(Settings.Secure.TAPS_APP_TO_EXIT,
+ OneHandedSettingsUtil.registerSettingsKeyObserver(Settings.Secure.TAPS_APP_TO_EXIT,
mContext.getContentResolver(), mTaskChangeExitObserver);
- mSettingUtil.registerSettingsKeyObserver(
+ OneHandedSettingsUtil.registerSettingsKeyObserver(
Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED,
mContext.getContentResolver(), mSwipeToNotificationEnabledObserver);
}
private void updateSettings() {
- mOneHandedManager.setOneHandedEnabled(
- mSettingUtil.getSettingsOneHandedModeEnabled(mContext.getContentResolver()));
- mTimeoutHandler.setTimeout(
- mSettingUtil.getSettingsOneHandedModeTimeout(mContext.getContentResolver()));
- mOneHandedManager.setTaskChangeToExit(
- mSettingUtil.getSettingsTapsAppToExit(mContext.getContentResolver()));
- mOneHandedManager.setSwipeToNotificationEnabled(
- mSettingUtil.getSettingsSwipeToNotificationEnabled(mContext.getContentResolver()));
+ mOneHandedManager.setOneHandedEnabled(OneHandedSettingsUtil
+ .getSettingsOneHandedModeEnabled(mContext.getContentResolver()));
+ mTimeoutHandler.setTimeout(OneHandedSettingsUtil
+ .getSettingsOneHandedModeTimeout(mContext.getContentResolver()));
+ mOneHandedManager.setTaskChangeToExit(OneHandedSettingsUtil
+ .getSettingsTapsAppToExit(mContext.getContentResolver()));
+ mOneHandedManager.setSwipeToNotificationEnabled(OneHandedSettingsUtil
+ .getSettingsSwipeToNotificationEnabled(mContext.getContentResolver()));
}
@Override
@@ -326,9 +322,7 @@ public class OneHandedUI extends SystemUI implements CommandQueue.Callbacks, Dum
mTimeoutHandler.dump(fd, pw, args);
}
- if (mSettingUtil != null) {
- mSettingUtil.dump(pw, innerPrefix, mContext.getContentResolver());
- }
+ OneHandedSettingsUtil.dump(pw, innerPrefix, mContext.getContentResolver());
if (mOverlayManager != null) {
OverlayInfo info = null;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index d03082e6b442..ecdd7780a3f4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -61,12 +61,18 @@ import android.view.MotionEvent;
import android.view.Surface;
import android.view.accessibility.AccessibilityManager;
+import androidx.annotation.NonNull;
+
import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.util.ScreenshotHelper;
import com.android.systemui.Dumpable;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.NavigationBar;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.onehanded.OneHandedUI;
import com.android.systemui.pip.PipAnimationController;
import com.android.systemui.pip.PipUI;
@@ -81,10 +87,6 @@ import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.NavigationBarController;
-import com.android.systemui.statusbar.phone.NavigationBarFragment;
-import com.android.systemui.statusbar.phone.NavigationBarView;
-import com.android.systemui.statusbar.phone.NavigationModeController;
import com.android.systemui.statusbar.phone.NotificationShadeWindowController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
@@ -124,7 +126,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
private final Optional<Divider> mDividerOptional;
private SysUiState mSysUiState;
private final Handler mHandler;
- private final NavigationBarController mNavBarController;
+ private final Lazy<NavigationBarController> mNavBarControllerLazy;
private final NotificationShadeWindowController mStatusBarWinController;
private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser;
private final ComponentName mRecentsComponentName;
@@ -598,7 +600,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Inject
public OverviewProxyService(Context context, CommandQueue commandQueue,
- NavigationBarController navBarController, NavigationModeController navModeController,
+ Lazy<NavigationBarController> navBarControllerLazy, NavigationModeController navModeController,
NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,
PipUI pipUI, Optional<Divider> dividerOptional,
Optional<Lazy<StatusBar>> statusBarOptionalLazy, OneHandedUI oneHandedUI,
@@ -608,7 +610,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
mPipUI = pipUI;
mStatusBarOptionalLazy = statusBarOptionalLazy;
mHandler = new Handler();
- mNavBarController = navBarController;
+ mNavBarControllerLazy = navBarControllerLazy;
mStatusBarWinController = statusBarWinController;
mConnectionBackoffAttempts = 0;
mDividerOptional = dividerOptional;
@@ -677,10 +679,10 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
private void updateSystemUiStateFlags() {
- final NavigationBarFragment navBarFragment =
- mNavBarController.getDefaultNavigationBarFragment();
+ final NavigationBar navBarFragment =
+ mNavBarControllerLazy.get().getDefaultNavigationBar();
final NavigationBarView navBarView =
- mNavBarController.getNavigationBarView(mContext.getDisplayId());
+ mNavBarControllerLazy.get().getNavigationBarView(mContext.getDisplayId());
if (SysUiState.DEBUG) {
Log.d(TAG_OPS, "Updating sysui state flags: navBarFragment=" + navBarFragment
+ " navBarView=" + navBarView);
@@ -808,7 +810,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
@Override
- public void addCallback(OverviewProxyListener listener) {
+ public void addCallback(@NonNull OverviewProxyListener listener) {
if (!mConnectionCallbacks.contains(listener)) {
mConnectionCallbacks.add(listener);
}
@@ -817,7 +819,7 @@ public class OverviewProxyService extends CurrentUserTracker implements
}
@Override
- public void removeCallback(OverviewProxyListener listener) {
+ public void removeCallback(@NonNull OverviewProxyListener listener) {
mConnectionCallbacks.remove(listener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index 3b3d9dde3b7e..9c5a3de4523a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -466,23 +466,22 @@ public class RecentsOnboarding {
}
public void dump(PrintWriter pw) {
- pw.println("RecentsOnboarding {");
- pw.println(" mTaskListenerRegistered: " + mTaskListenerRegistered);
- pw.println(" mOverviewProxyListenerRegistered: " + mOverviewProxyListenerRegistered);
- pw.println(" mLayoutAttachedToWindow: " + mLayoutAttachedToWindow);
- pw.println(" mHasDismissedSwipeUpTip: " + mHasDismissedSwipeUpTip);
- pw.println(" mHasDismissedQuickScrubTip: " + mHasDismissedQuickScrubTip);
- pw.println(" mNumAppsLaunchedSinceSwipeUpTipDismiss: "
+ pw.println("RecentsOnboarding");
+ pw.println(" mTaskListenerRegistered: " + mTaskListenerRegistered);
+ pw.println(" mOverviewProxyListenerRegistered: " + mOverviewProxyListenerRegistered);
+ pw.println(" mLayoutAttachedToWindow: " + mLayoutAttachedToWindow);
+ pw.println(" mHasDismissedSwipeUpTip: " + mHasDismissedSwipeUpTip);
+ pw.println(" mHasDismissedQuickScrubTip: " + mHasDismissedQuickScrubTip);
+ pw.println(" mNumAppsLaunchedSinceSwipeUpTipDismiss: "
+ mNumAppsLaunchedSinceSwipeUpTipDismiss);
- pw.println(" hasSeenSwipeUpOnboarding: " + hasSeenSwipeUpOnboarding());
- pw.println(" hasSeenQuickScrubOnboarding: " + hasSeenQuickScrubOnboarding());
- pw.println(" getDismissedSwipeUpOnboardingCount: "
+ pw.println(" hasSeenSwipeUpOnboarding: " + hasSeenSwipeUpOnboarding());
+ pw.println(" hasSeenQuickScrubOnboarding: " + hasSeenQuickScrubOnboarding());
+ pw.println(" getDismissedSwipeUpOnboardingCount: "
+ getDismissedSwipeUpOnboardingCount());
- pw.println(" hasDismissedQuickScrubOnboardingOnce: "
+ pw.println(" hasDismissedQuickScrubOnboardingOnce: "
+ hasDismissedQuickScrubOnboardingOnce());
- pw.println(" getOpenedOverviewCount: " + getOpenedOverviewCount());
- pw.println(" getOpenedOverviewFromHomeCount: " + getOpenedOverviewFromHomeCount());
- pw.println(" }");
+ pw.println(" getOpenedOverviewCount: " + getOpenedOverviewCount());
+ pw.println(" getOpenedOverviewFromHomeCount: " + getOpenedOverviewFromHomeCount());
}
private WindowManager.LayoutParams getWindowLayoutParams(int gravity, int x) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 387490311644..6afc75624a9f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -51,8 +51,8 @@ import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.statusbar.phone.NavigationBarView;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.leak.RotationUtils;
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
index 82ac1f6f6a33..4da2bb66d41b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
@@ -26,6 +26,8 @@ import android.os.CountDownTimer;
import android.os.UserHandle;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.statusbar.policy.CallbackController;
@@ -191,12 +193,12 @@ public class RecordingController
}
@Override
- public void addCallback(RecordingStateChangeCallback listener) {
+ public void addCallback(@NonNull RecordingStateChangeCallback listener) {
mListeners.add(listener);
}
@Override
- public void removeCallback(RecordingStateChangeCallback listener) {
+ public void removeCallback(@NonNull RecordingStateChangeCallback listener) {
mListeners.remove(listener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 1638dd9664a4..4673ec73c25a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -49,6 +49,8 @@ import android.util.SparseArray;
import android.view.InsetsState.InternalInsetsType;
import android.view.WindowInsetsController.Appearance;
+import androidx.annotation.NonNull;
+
import com.android.internal.os.SomeArgs;
import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.StatusBarIcon;
@@ -391,7 +393,8 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
&& !ONLY_CORE_APPS;
}
- public void addCallback(Callbacks callbacks) {
+ @Override
+ public void addCallback(@NonNull Callbacks callbacks) {
mCallbacks.add(callbacks);
// TODO(b/117478341): find a better way to pass disable flags by display.
for (int i = 0; i < mDisplayDisabled.size(); i++) {
@@ -402,7 +405,8 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
}
}
- public void removeCallback(Callbacks callbacks) {
+ @Override
+ public void removeCallback(@NonNull Callbacks callbacks) {
mCallbacks.remove(callbacks);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
deleted file mode 100644
index 2638d28733e8..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.Display;
-import android.view.IWindowManager;
-import android.view.View;
-import android.view.WindowManagerGlobal;
-
-import androidx.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.statusbar.RegisterStatusBarResult;
-import com.android.systemui.Dependency;
-import com.android.systemui.assist.AssistHandleViewController;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.fragments.FragmentHostManager;
-import com.android.systemui.plugins.DarkIconDispatcher;
-import com.android.systemui.statusbar.CommandQueue.Callbacks;
-import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
-import com.android.systemui.statusbar.phone.LightBarController;
-import com.android.systemui.statusbar.phone.NavigationBarFragment;
-import com.android.systemui.statusbar.phone.NavigationBarView;
-import com.android.systemui.statusbar.phone.NavigationModeController;
-import com.android.systemui.statusbar.policy.BatteryController;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-
-/** A controller to handle navigation bars. */
-@Singleton
-public class NavigationBarController implements Callbacks {
-
- private static final String TAG = NavigationBarController.class.getSimpleName();
-
- private final Context mContext;
- private final Handler mHandler;
- private final DisplayManager mDisplayManager;
-
- /** A displayId - nav bar maps. */
- @VisibleForTesting
- SparseArray<NavigationBarFragment> mNavigationBars = new SparseArray<>();
-
- @Inject
- public NavigationBarController(Context context, @Main Handler handler,
- CommandQueue commandQueue) {
- mContext = context;
- mHandler = handler;
- mDisplayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
- commandQueue.addCallback(this);
- }
-
- @Override
- public void onDisplayRemoved(int displayId) {
- removeNavigationBar(displayId);
- }
-
- @Override
- public void onDisplayReady(int displayId) {
- Display display = mDisplayManager.getDisplay(displayId);
- createNavigationBar(display, null);
- }
-
- // TODO(b/117478341): I use {@code includeDefaultDisplay} to make this method compatible to
- // CarStatusBar because they have their own nav bar. Think about a better way for it.
- /**
- * Creates navigation bars when car/status bar initializes.
- *
- * @param includeDefaultDisplay {@code true} to create navigation bar on default display.
- */
- public void createNavigationBars(final boolean includeDefaultDisplay,
- RegisterStatusBarResult result) {
- Display[] displays = mDisplayManager.getDisplays();
- for (Display display : displays) {
- if (includeDefaultDisplay || display.getDisplayId() != DEFAULT_DISPLAY) {
- createNavigationBar(display, result);
- }
- }
- }
-
- /**
- * Adds a navigation bar on default display or an external display if the display supports
- * system decorations.
- *
- * @param display the display to add navigation bar on.
- */
- @VisibleForTesting
- void createNavigationBar(Display display, RegisterStatusBarResult result) {
- if (display == null) {
- return;
- }
-
- final int displayId = display.getDisplayId();
- final boolean isOnDefaultDisplay = displayId == DEFAULT_DISPLAY;
- final IWindowManager wms = WindowManagerGlobal.getWindowManagerService();
-
- try {
- if (!wms.hasNavigationBar(displayId)) {
- return;
- }
- } catch (RemoteException e) {
- // Cannot get wms, just return with warning message.
- Log.w(TAG, "Cannot get WindowManager.");
- return;
- }
- final Context context = isOnDefaultDisplay
- ? mContext
- : mContext.createDisplayContext(display);
- NavigationBarFragment.create(context, (tag, fragment) -> {
- NavigationBarFragment navBar = (NavigationBarFragment) fragment;
-
- // Unfortunately, we still need it because status bar needs LightBarController
- // before notifications creation. We cannot directly use getLightBarController()
- // from NavigationBarFragment directly.
- LightBarController lightBarController = isOnDefaultDisplay
- ? Dependency.get(LightBarController.class)
- : new LightBarController(context,
- Dependency.get(DarkIconDispatcher.class),
- Dependency.get(BatteryController.class),
- Dependency.get(NavigationModeController.class));
- navBar.setLightBarController(lightBarController);
-
- // TODO(b/118592525): to support multi-display, we start to add something which is
- // per-display, while others may be global. I think it's time to add
- // a new class maybe named DisplayDependency to solve per-display
- // Dependency problem.
- AutoHideController autoHideController = isOnDefaultDisplay
- ? Dependency.get(AutoHideController.class)
- : new AutoHideController(context, mHandler,
- Dependency.get(IWindowManager.class));
- navBar.setAutoHideController(autoHideController);
- navBar.restoreAppearanceAndTransientState();
- mNavigationBars.put(displayId, navBar);
-
- if (result != null) {
- navBar.setImeWindowStatus(display.getDisplayId(), result.mImeToken,
- result.mImeWindowVis, result.mImeBackDisposition,
- result.mShowImeSwitcher);
- }
- });
- }
-
- private void removeNavigationBar(int displayId) {
- NavigationBarFragment navBar = mNavigationBars.get(displayId);
- if (navBar != null) {
- navBar.setAutoHideController(/* autoHideController */ null);
- View navigationWindow = navBar.getView().getRootView();
- WindowManagerGlobal.getInstance()
- .removeView(navigationWindow, true /* immediate */);
- // Also remove FragmentHostState here in case that onViewDetachedFromWindow has not yet
- // invoked after display removal.
- FragmentHostManager.removeAndDestroy(navigationWindow);
- mNavigationBars.remove(displayId);
- }
- }
-
- /** @see NavigationBarFragment#checkNavBarModes() */
- public void checkNavBarModes(int displayId) {
- NavigationBarFragment navBar = mNavigationBars.get(displayId);
- if (navBar != null) {
- navBar.checkNavBarModes();
- }
- }
-
- /** @see NavigationBarFragment#finishBarAnimations() */
- public void finishBarAnimations(int displayId) {
- NavigationBarFragment navBar = mNavigationBars.get(displayId);
- if (navBar != null) {
- navBar.finishBarAnimations();
- }
- }
-
- /** @see NavigationBarFragment#touchAutoDim() */
- public void touchAutoDim(int displayId) {
- NavigationBarFragment navBar = mNavigationBars.get(displayId);
- if (navBar != null) {
- navBar.touchAutoDim();
- }
- }
-
- /** @see NavigationBarFragment#transitionTo(int, boolean) */
- public void transitionTo(int displayId, @TransitionMode int barMode, boolean animate) {
- NavigationBarFragment navBar = mNavigationBars.get(displayId);
- if (navBar != null) {
- navBar.transitionTo(barMode, animate);
- }
- }
-
- /** @see NavigationBarFragment#disableAnimationsDuringHide(long) */
- public void disableAnimationsDuringHide(int displayId, long delay) {
- NavigationBarFragment navBar = mNavigationBars.get(displayId);
- if (navBar != null) {
- navBar.disableAnimationsDuringHide(delay);
- }
- }
-
- /** @return {@link NavigationBarView} on the default display. */
- public @Nullable NavigationBarView getDefaultNavigationBarView() {
- return getNavigationBarView(DEFAULT_DISPLAY);
- }
-
- /**
- * @param displayId the ID of display which Navigation bar is on
- * @return {@link NavigationBarView} on the display with {@code displayId}.
- * {@code null} if no navigation bar on that display.
- */
- public @Nullable NavigationBarView getNavigationBarView(int displayId) {
- NavigationBarFragment navBar = mNavigationBars.get(displayId);
- return (navBar == null) ? null : (NavigationBarView) navBar.getView();
- }
-
- /** @return {@link NavigationBarFragment} on the default display. */
- @Nullable
- public NavigationBarFragment getDefaultNavigationBarFragment() {
- return mNavigationBars.get(DEFAULT_DISPLAY);
- }
-
- /** @return {@link AssistHandleViewController} (only on the default display). */
- @Nullable
- public AssistHandleViewController getAssistHandlerViewController() {
- NavigationBarFragment navBar = getDefaultNavigationBarFragment();
- return navBar == null ? null : navBar.getAssistHandlerViewController();
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 02a8feec3fa9..f272be477f51 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -491,7 +491,6 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
}
}
- row.showAppOpsIcons(entry.mActiveAppOps);
row.showFeedbackIcon(mAssistantFeedbackController.showFeedbackIndicator(entry));
row.setLastAudiblyAlertedMs(entry.getLastAudiblyAlertedMs());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java
index 0a7ee3b0ebf0..2aba1038a97d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java
@@ -28,8 +28,8 @@ import android.widget.TextView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.settingslib.WirelessUtils;
-import com.android.systemui.DemoMode;
import com.android.systemui.Dependency;
+import com.android.systemui.demomode.DemoModeCommandReceiver;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.policy.NetworkController;
@@ -40,7 +40,8 @@ import com.android.systemui.tuner.TunerService.Tunable;
import java.util.List;
-public class OperatorNameView extends TextView implements DemoMode, DarkReceiver,
+/** Shows the operator name */
+public class OperatorNameView extends TextView implements DemoModeCommandReceiver, DarkReceiver,
SignalCallback, Tunable {
private static final String KEY_SHOW_OPERATOR_NAME = "show_operator_name";
@@ -103,14 +104,18 @@ public class OperatorNameView extends TextView implements DemoMode, DarkReceiver
@Override
public void dispatchDemoCommand(String command, Bundle args) {
- if (!mDemoMode && command.equals(COMMAND_ENTER)) {
- mDemoMode = true;
- } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
- mDemoMode = false;
- update();
- } else if (mDemoMode && command.equals(COMMAND_OPERATOR)) {
- setText(args.getString("name"));
- }
+ setText(args.getString("name"));
+ }
+
+ @Override
+ public void onDemoModeStarted() {
+ mDemoMode = true;
+ }
+
+ @Override
+ public void onDemoModeFinished() {
+ mDemoMode = false;
+ update();
}
private void update() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 2bef355d59f3..f93078f8b586 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -23,6 +23,8 @@ import android.util.FloatProperty;
import android.util.Log;
import android.view.animation.Interpolator;
+import androidx.annotation.NonNull;
+
import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.DejankUtils;
@@ -276,7 +278,7 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
}
@Override
- public void addCallback(StateListener listener) {
+ public void addCallback(@NonNull StateListener listener) {
synchronized (mListeners) {
addListenerInternalLocked(listener, Integer.MAX_VALUE);
}
@@ -316,7 +318,7 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
@Override
- public void removeCallback(StateListener listener) {
+ public void removeCallback(@NonNull StateListener listener) {
synchronized (mListeners) {
mListeners.removeIf((it) -> it.mListener.equals(listener));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java
index 68ec6b620a53..2f1208879ebc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java
@@ -82,14 +82,9 @@ public class AppOpsCoordinator implements Coordinator {
// extend the lifetime of foreground notification services to show for at least 5 seconds
mNotifPipeline.addNotificationLifetimeExtender(mForegroundLifetimeExtender);
- // listen for new notifications to add appOps
- mNotifPipeline.addCollectionListener(mNotifCollectionListener);
-
// filter out foreground service notifications that aren't necessary anymore
mNotifPipeline.addPreGroupFilter(mNotifFilter);
- // when appOps change, update any relevant notifications to update appOps for
- mAppOpsController.addCallback(ForegroundServiceController.APP_OPS, this::onAppOpsChanged);
}
public NotifSection getSection() {
@@ -186,35 +181,6 @@ public class AppOpsCoordinator implements Coordinator {
};
/**
- * Adds appOps to incoming and updating notifications
- */
- private NotifCollectionListener mNotifCollectionListener = new NotifCollectionListener() {
- @Override
- public void onEntryAdded(NotificationEntry entry) {
- tagAppOps(entry);
- }
-
- @Override
- public void onEntryUpdated(NotificationEntry entry) {
- tagAppOps(entry);
- }
-
- private void tagAppOps(NotificationEntry entry) {
- final StatusBarNotification sbn = entry.getSbn();
- // note: requires that the ForegroundServiceController is updating their appOps first
- ArraySet<Integer> activeOps =
- mForegroundServiceController.getAppOps(
- sbn.getUser().getIdentifier(),
- sbn.getPackageName());
-
- entry.mActiveAppOps.clear();
- if (activeOps != null) {
- entry.mActiveAppOps.addAll(activeOps);
- }
- }
- };
-
- /**
* Puts foreground service notifications into its own section.
*/
private final NotifSection mNotifSection = new NotifSection("ForegroundService") {
@@ -230,53 +196,4 @@ public class AppOpsCoordinator implements Coordinator {
return false;
}
};
-
- private void onAppOpsChanged(int code, int uid, String packageName, boolean active) {
- mMainExecutor.execute(() -> handleAppOpsChanged(code, uid, packageName, active));
- }
-
- /**
- * Update the appOp for the posted notification associated with the current foreground service
- *
- * @param code code for appOp to add/remove
- * @param uid of user the notification is sent to
- * @param packageName package that created the notification
- * @param active whether the appOpCode is active or not
- */
- private void handleAppOpsChanged(int code, int uid, String packageName, boolean active) {
- Assert.isMainThread();
-
- int userId = UserHandle.getUserId(uid);
-
- // Update appOps of the app's posted notifications with standard layouts
- final ArraySet<String> notifKeys =
- mForegroundServiceController.getStandardLayoutKeys(userId, packageName);
- if (notifKeys != null) {
- boolean changed = false;
- for (int i = 0; i < notifKeys.size(); i++) {
- final NotificationEntry entry = findNotificationEntryWithKey(notifKeys.valueAt(i));
- if (entry != null
- && uid == entry.getSbn().getUid()
- && packageName.equals(entry.getSbn().getPackageName())) {
- if (active) {
- changed |= entry.mActiveAppOps.add(code);
- } else {
- changed |= entry.mActiveAppOps.remove(code);
- }
- }
- }
- if (changed) {
- mNotifFilter.invalidateList();
- }
- }
- }
-
- private NotificationEntry findNotificationEntryWithKey(String key) {
- for (NotificationEntry entry : mNotifPipeline.getAllNotifs()) {
- if (entry.getKey().equals(key)) {
- return entry;
- }
- }
- return null;
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
index ee2bb6b1d190..3e110671d174 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
@@ -307,7 +307,7 @@ public class PreparationCoordinator implements Coordinator {
private void onInflationFinished(NotificationEntry entry) {
mLogger.logNotifInflated(entry.getKey());
mInflatingNotifs.remove(entry);
- mViewBarn.registerViewForEntry(entry, entry.getRow());
+ mViewBarn.registerViewForEntry(entry, entry.getRowController());
mInflationStates.put(entry, STATE_INFLATED);
mNotifInflatingFilter.invalidateList();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index 8849824380d3..f90ec0b4f42a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -136,6 +136,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
.expandableNotificationRow(row)
.notificationEntry(entry)
.onExpandClickListener(mPresenter)
+ .listContainer(mListContainer)
.build();
ExpandableNotificationRowController rowController =
component.getExpandableNotificationRowController();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
index 9782c3ef55fe..1c02c62602cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
@@ -29,8 +29,7 @@ import com.android.systemui.statusbar.notification.collection.ShadeListBuilder;
import com.android.systemui.statusbar.notification.collection.coalescer.GroupCoalescer;
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
-import com.android.systemui.statusbar.notification.collection.render.NotifViewManager;
-import com.android.systemui.statusbar.notification.collection.render.NotifViewManagerBuilder;
+import com.android.systemui.statusbar.notification.collection.render.ShadeViewManagerFactory;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import java.io.FileDescriptor;
@@ -51,7 +50,7 @@ public class NotifPipelineInitializer implements Dumpable {
private final NotifCoordinators mNotifPluggableCoordinators;
private final NotifInflaterImpl mNotifInflater;
private final DumpManager mDumpManager;
- private final NotifViewManagerBuilder mNotifViewManagerBuilder;
+ private final ShadeViewManagerFactory mShadeViewManagerFactory;
private final FeatureFlags mFeatureFlags;
@@ -64,7 +63,7 @@ public class NotifPipelineInitializer implements Dumpable {
NotifCoordinators notifCoordinators,
NotifInflaterImpl notifInflater,
DumpManager dumpManager,
- NotifViewManagerBuilder notifViewManagerBuilder,
+ ShadeViewManagerFactory shadeViewManagerFactory,
FeatureFlags featureFlags) {
mPipelineWrapper = pipelineWrapper;
mGroupCoalescer = groupCoalescer;
@@ -73,8 +72,8 @@ public class NotifPipelineInitializer implements Dumpable {
mNotifPluggableCoordinators = notifCoordinators;
mDumpManager = dumpManager;
mNotifInflater = notifInflater;
+ mShadeViewManagerFactory = shadeViewManagerFactory;
mFeatureFlags = featureFlags;
- mNotifViewManagerBuilder = notifViewManagerBuilder;
}
/** Hooks the new pipeline up to NotificationManager */
@@ -95,8 +94,7 @@ public class NotifPipelineInitializer implements Dumpable {
// Wire up pipeline
if (mFeatureFlags.isNewNotifPipelineRenderingEnabled()) {
- NotifViewManager notifViewManager = mNotifViewManagerBuilder.build(listContainer);
- notifViewManager.attach(mListBuilder);
+ mShadeViewManagerFactory.create(listContainer).attach(mListBuilder);
}
mListBuilder.attach(mNotifCollection);
mNotifCollection.attach(mGroupCoalescer);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt
new file mode 100644
index 000000000000..67f7b1c09df3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.render
+
+import android.view.View
+import java.lang.RuntimeException
+import java.lang.StringBuilder
+
+/**
+ * A controller that represents a single unit of addable/removable view(s) in the notification
+ * shade. Some nodes are just a single view (such as a header), while some might involve many views
+ * (such as a notification row).
+ *
+ * It's possible for nodes to support having child nodes (for example, some notification rows
+ * contain other notification rows). If so, they must implement all of the child-related methods
+ * below.
+ */
+interface NodeController {
+ /** A string that uniquely(ish) represents the node in the tree. Used for debugging. */
+ val nodeLabel: String
+
+ val view: View
+
+ fun getChildAt(index: Int): View? {
+ throw RuntimeException("Not supported")
+ }
+
+ fun getChildCount(): Int {
+ throw RuntimeException("Not supported")
+ }
+
+ fun addChildAt(child: NodeController, index: Int) {
+ throw RuntimeException("Not supported")
+ }
+
+ fun moveChildTo(child: NodeController, index: Int) {
+ throw RuntimeException("Not supported")
+ }
+
+ fun removeChild(child: NodeController, isTransfer: Boolean) {
+ throw RuntimeException("Not supported")
+ }
+}
+
+/**
+ * Used to specify the tree of [NodeController]s that currently make up the shade.
+ */
+interface NodeSpec {
+ val parent: NodeSpec?
+ val controller: NodeController
+ val children: List<NodeSpec>
+}
+
+class NodeSpecImpl(
+ override val parent: NodeSpec?,
+ override val controller: NodeController
+) : NodeSpec {
+ override val children = mutableListOf<NodeSpec>()
+}
+
+/**
+ * Converts a tree spec to human-readable string, for dumping purposes.
+ */
+fun treeSpecToStr(tree: NodeSpec): String {
+ return StringBuilder().also { treeSpecToStrHelper(tree, it, "") }.toString()
+}
+
+private fun treeSpecToStrHelper(tree: NodeSpec, sb: StringBuilder, indent: String) {
+ sb.append("${indent}ns{${tree.controller.nodeLabel}")
+ if (tree.children.isNotEmpty()) {
+ val childIndent = "$indent "
+ for (child in tree.children) {
+ treeSpecToStrHelper(child, sb, childIndent)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt
index 54000950e3ef..00fd09dd662e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt
@@ -18,18 +18,19 @@ package com.android.systemui.statusbar.notification.collection.render
import android.view.textclassifier.Log
import com.android.systemui.statusbar.notification.collection.ListEntry
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController
import javax.inject.Inject
import javax.inject.Singleton
/**
- * The ViewBarn is just a map from [ListEntry] to an instance of an [ExpandableNotificationRow].
+ * The ViewBarn is just a map from [ListEntry] to an instance of an
+ * [ExpandableNotificationRowController].
*/
@Singleton
class NotifViewBarn @Inject constructor() {
- private val rowMap = mutableMapOf<String, ExpandableNotificationRow>()
+ private val rowMap = mutableMapOf<String, ExpandableNotificationRowController>()
- fun requireView(forEntry: ListEntry): ExpandableNotificationRow {
+ fun requireView(forEntry: ListEntry): ExpandableNotificationRowController {
if (DEBUG) {
Log.d(TAG, "requireView: $forEntry.key")
}
@@ -41,11 +42,11 @@ class NotifViewBarn @Inject constructor() {
return li
}
- fun registerViewForEntry(entry: ListEntry, view: ExpandableNotificationRow) {
+ fun registerViewForEntry(entry: ListEntry, controller: ExpandableNotificationRowController) {
if (DEBUG) {
Log.d(TAG, "registerViewForEntry: $entry.key")
}
- rowMap[entry.key] = view
+ rowMap[entry.key] = controller
}
fun removeViewForEntry(entry: ListEntry) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManager.kt
deleted file mode 100644
index f2e2c39ab612..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManager.kt
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.render
-
-import android.annotation.MainThread
-import android.view.View
-import com.android.systemui.statusbar.notification.collection.GroupEntry
-import com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY
-import com.android.systemui.statusbar.notification.collection.ListEntry
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import com.android.systemui.statusbar.notification.collection.ShadeListBuilder
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import javax.inject.Inject
-
-/**
- * A consumer of a Notification tree built by [ShadeListBuilder] which will update the notification
- * presenter with the minimum operations required to make the old tree match the new one
- */
-@MainThread
-class NotifViewManager constructor(
- private val listContainer: NotificationListContainer,
- private val viewBarn: NotifViewBarn,
- private val logger: NotifViewManagerLogger
-) {
- private val rootNode = RootWrapper(listContainer)
- private val rows = mutableMapOf<ListEntry, RowNode>()
-
- fun attach(listBuilder: ShadeListBuilder) {
- listBuilder.setOnRenderListListener(::onNewNotifTree)
- }
-
- private fun onNewNotifTree(tree: List<ListEntry>) {
- // Step 1: Detach all views whose parents have changed
- detachRowsWithModifiedParents()
-
- // Step 2: Attach all new views and reattach all views whose parents changed.
- // Also reorder existing children to match the spec we've received
- val orderChanged = addAndReorderChildren(rootNode, tree)
- if (orderChanged) {
- listContainer.generateChildOrderChangedEvent()
- }
- }
-
- private fun detachRowsWithModifiedParents() {
- val toRemove = mutableListOf<ListEntry>()
- for (row in rows.values) {
- val oldParentEntry = row.nodeParent?.entry
- val newParentEntry = row.entry.parent
-
- if (newParentEntry != oldParentEntry) {
- // If the parent is null, then we should remove the child completely. If not, then
- // the parent merely changed: we'll detach it for now and then attach it to the
- // new parent in step 2.
- val isTransfer = newParentEntry != null
- if (!isTransfer) {
- toRemove.add(row.entry)
- }
-
- if (!isTransfer && !isAttachedToRootEntry(oldParentEntry)) {
- // If our view parent has also been removed (i.e. is no longer attached to the
- // root entry) then we skip removing the child here
- logger.logSkippingDetach(row.entry.key, row.nodeParent?.entry?.key)
- } else {
- logger.logDetachingChild(
- row.entry.key,
- isTransfer,
- oldParentEntry?.key,
- newParentEntry?.key)
- row.nodeParent?.removeChild(row, isTransfer)
- row.nodeParent = null
- }
- }
- }
- rows.keys.removeAll(toRemove)
- }
-
- private fun addAndReorderChildren(parent: ParentNode, childEntries: List<ListEntry>): Boolean {
- var orderChanged = false
- for ((index, entry) in childEntries.withIndex()) {
- val row = getRowNode(entry)
- val currView = parent.getChildViewAt(index)
- if (currView != row.view) {
- when (row.nodeParent) {
- null -> {
- logger.logAttachingChild(row.entry.key, parent.entry.key)
- parent.addChildAt(row, index)
- row.nodeParent = parent
- }
- parent -> {
- logger.logMovingChild(row.entry.key, parent.entry.key, index)
- parent.moveChild(row, index)
- orderChanged = true
- }
- else -> {
- throw IllegalStateException("Child ${row.entry.key} should have parent " +
- "${parent.entry.key} but is actually " +
- "${row.nodeParent?.entry?.key}")
- }
- }
- }
- if (row is GroupWrapper) {
- val childOrderChanged = addAndReorderChildren(row, row.entry.children)
- orderChanged = orderChanged || childOrderChanged
- }
- }
- // TODO: setUntruncatedChildCount
-
- return orderChanged
- }
-
- private fun getRowNode(entry: ListEntry): RowNode {
- return rows.getOrPut(entry) {
- when (entry) {
- is NotificationEntry -> RowWrapper(entry, viewBarn.requireView(entry))
- is GroupEntry ->
- GroupWrapper(
- entry,
- viewBarn.requireView(checkNotNull(entry.summary)),
- listContainer)
- else -> throw RuntimeException(
- "Unexpected entry type for ${entry.key}: ${entry.javaClass}")
- }
- }
- }
-}
-
-class NotifViewManagerBuilder @Inject constructor(
- private val viewBarn: NotifViewBarn,
- private val logger: NotifViewManagerLogger
-) {
- fun build(listContainer: NotificationListContainer): NotifViewManager {
- return NotifViewManager(listContainer, viewBarn, logger)
- }
-}
-
-private fun isAttachedToRootEntry(entry: ListEntry?): Boolean {
- return when (entry) {
- null -> false
- ROOT_ENTRY -> true
- else -> isAttachedToRootEntry(entry.parent)
- }
-}
-
-private interface Node {
- val entry: ListEntry
- val nodeParent: ParentNode?
-}
-
-private interface ParentNode : Node {
- fun getChildViewAt(index: Int): View?
- fun addChildAt(child: RowNode, index: Int)
- fun moveChild(child: RowNode, index: Int)
- fun removeChild(child: RowNode, isTransfer: Boolean)
-}
-
-private interface RowNode : Node {
- val view: ExpandableNotificationRow
- override var nodeParent: ParentNode?
-}
-
-private class RootWrapper(
- private val listContainer: NotificationListContainer
-) : ParentNode {
- override val entry: ListEntry = ROOT_ENTRY
- override val nodeParent: ParentNode? = null
-
- override fun getChildViewAt(index: Int): View? {
- return listContainer.getContainerChildAt(index)
- }
-
- override fun addChildAt(child: RowNode, index: Int) {
- listContainer.addContainerViewAt(child.view, index)
- }
-
- override fun moveChild(child: RowNode, index: Int) {
- listContainer.changeViewPosition(child.view, index)
- }
-
- override fun removeChild(child: RowNode, isTransfer: Boolean) {
- if (isTransfer) {
- listContainer.setChildTransferInProgress(true)
- }
- listContainer.removeContainerView(child.view)
- if (isTransfer) {
- listContainer.setChildTransferInProgress(false)
- }
- }
-}
-
-private class GroupWrapper(
- override val entry: GroupEntry,
- override val view: ExpandableNotificationRow,
- val listContainer: NotificationListContainer
-) : RowNode, ParentNode {
-
- override var nodeParent: ParentNode? = null
-
- override fun getChildViewAt(index: Int): View? {
- return view.getChildNotificationAt(index)
- }
-
- override fun addChildAt(child: RowNode, index: Int) {
- view.addChildNotification(child.view, index)
- listContainer.notifyGroupChildAdded(child.view)
- }
-
- override fun moveChild(child: RowNode, index: Int) {
- view.removeChildNotification(child.view)
- view.addChildNotification(child.view, index)
- }
-
- override fun removeChild(child: RowNode, isTransfer: Boolean) {
- view.removeChildNotification(child.view)
- if (isTransfer) {
- listContainer.notifyGroupChildRemoved(child.view, view)
- }
- }
-}
-
-private class RowWrapper(
- override val entry: NotificationEntry,
- override val view: ExpandableNotificationRow
-) : RowNode {
- override var nodeParent: ParentNode? = null
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RootNodeController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RootNodeController.kt
new file mode 100644
index 000000000000..e8124944bcb0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RootNodeController.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.render
+
+import android.view.View
+import com.android.systemui.statusbar.notification.row.ExpandableView
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer
+
+/**
+ * Temporary wrapper around [NotificationListContainer], for use by [ShadeViewDiffer]. Long term,
+ * we should just modify NLC to implement the NodeController interface.
+ */
+class RootNodeController(
+ private val listContainer: NotificationListContainer
+) : NodeController {
+ override val nodeLabel: String = "<root>"
+ override val view: View = listContainer as View
+
+ override fun getChildAt(index: Int): View? {
+ return listContainer.getContainerChildAt(index)
+ }
+
+ override fun getChildCount(): Int {
+ return listContainer.containerChildCount
+ }
+
+ override fun addChildAt(child: NodeController, index: Int) {
+ listContainer.addContainerViewAt(child.view, index)
+ }
+
+ override fun moveChildTo(child: NodeController, index: Int) {
+ listContainer.changeViewPosition(child.view as ExpandableView, index)
+ }
+
+ override fun removeChild(child: NodeController, isTransfer: Boolean) {
+ if (isTransfer) {
+ listContainer.setChildTransferInProgress(true)
+ }
+ listContainer.removeContainerView(child.view)
+ if (isTransfer) {
+ listContainer.setChildTransferInProgress(false)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
new file mode 100644
index 000000000000..019520f18982
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.render
+
+import android.annotation.MainThread
+import android.view.View
+import com.android.systemui.util.kotlin.transform
+
+/**
+ * Given a "spec" that describes a "tree" of views, adds and removes views from the
+ * [rootController] and its children until the actual tree matches the spec.
+ *
+ * Every node in the spec tree must specify both a view and its associated [NodeController].
+ * Commands to add/remove/reorder children are sent to the controller. How the controller
+ * interprets these commands is left to its own discretion -- it might add them directly to its
+ * associated view or to some subview container.
+ *
+ * It's possible for nodes to mix "unmanaged" views in alongside managed ones within the same
+ * container. In this case, whenever the differ runs it will move all unmanaged views to the end
+ * of the node's child list.
+ */
+@MainThread
+class ShadeViewDiffer(
+ rootController: NodeController,
+ private val logger: ShadeViewDifferLogger
+) {
+ private val rootNode = ShadeNode(rootController)
+ private val nodes = mutableMapOf(rootController to rootNode)
+ private val views = mutableMapOf<View, ShadeNode>()
+
+ /**
+ * Adds and removes views from the root (and its children) until their structure matches the
+ * provided [spec]. The root node of the spec must match the root controller passed to the
+ * differ's constructor.
+ */
+ fun applySpec(spec: NodeSpec) {
+ val specMap = treeToMap(spec)
+
+ if (spec.controller != rootNode.controller) {
+ throw IllegalArgumentException("Tree root ${spec.controller.nodeLabel} does not " +
+ "match own root at ${rootNode.label}")
+ }
+
+ detachChildren(rootNode, specMap)
+ attachChildren(rootNode, specMap)
+ }
+
+ /**
+ * If [view] is managed by this differ, then returns the label of the view's controller.
+ * Otherwise returns View.toString().
+ *
+ * For debugging purposes.
+ */
+ fun getViewLabel(view: View): String {
+ return views[view]?.label ?: view.toString()
+ }
+
+ private fun detachChildren(
+ parentNode: ShadeNode,
+ specMap: Map<NodeController, NodeSpec>
+ ) {
+ val parentSpec = specMap[parentNode.controller]
+
+ for (i in parentNode.getChildCount() - 1 downTo 0) {
+ val childView = parentNode.getChildAt(i)
+ views[childView]?.let { childNode ->
+ val childSpec = specMap[childNode.controller]
+
+ maybeDetachChild(parentNode, parentSpec, childNode, childSpec)
+
+ if (childNode.controller.getChildCount() > 0) {
+ detachChildren(childNode, specMap)
+ }
+ }
+ }
+ }
+
+ private fun maybeDetachChild(
+ parentNode: ShadeNode,
+ parentSpec: NodeSpec?,
+ childNode: ShadeNode,
+ childSpec: NodeSpec?
+ ) {
+ val newParentNode = transform(childSpec?.parent) { getNode(it) }
+
+ if (newParentNode != parentNode) {
+ val childCompletelyRemoved = newParentNode == null
+
+ if (childCompletelyRemoved) {
+ nodes.remove(childNode.controller)
+ views.remove(childNode.controller.view)
+ }
+
+ if (childCompletelyRemoved && parentSpec == null) {
+ // If both the child and the parent are being removed at the same time, then
+ // keep the child attached to the parent for animation purposes
+ logger.logSkippingDetach(childNode.label, parentNode.label)
+ } else {
+ logger.logDetachingChild(
+ childNode.label,
+ !childCompletelyRemoved,
+ parentNode.label,
+ newParentNode?.label)
+ parentNode.removeChild(childNode, !childCompletelyRemoved)
+ childNode.parent = null
+ }
+ }
+ }
+
+ private fun attachChildren(
+ parentNode: ShadeNode,
+ specMap: Map<NodeController, NodeSpec>
+ ) {
+ val parentSpec = checkNotNull(specMap[parentNode.controller])
+
+ for ((index, childSpec) in parentSpec.children.withIndex()) {
+ val currView = parentNode.getChildAt(index)
+ val childNode = getNode(childSpec)
+
+ if (childNode.view != currView) {
+
+ when (childNode.parent) {
+ null -> {
+ // A new child (either newly created or coming from some other parent)
+ logger.logAttachingChild(childNode.label, parentNode.label)
+ parentNode.addChildAt(childNode, index)
+ childNode.parent = parentNode
+ }
+ parentNode -> {
+ // A pre-existing child, just in the wrong position. Move it into place
+ logger.logMovingChild(childNode.label, parentNode.label, index)
+ parentNode.moveChildTo(childNode, index)
+ }
+ else -> {
+ // Error: child still has a parent. We should have detached it in the
+ // previous step.
+ throw IllegalStateException("Child ${childNode.label} should have " +
+ "parent ${parentNode.label} but is actually " +
+ "${childNode.parent?.label}")
+ }
+ }
+ }
+
+ if (childSpec.children.isNotEmpty()) {
+ attachChildren(childNode, specMap)
+ }
+ }
+ }
+
+ private fun getNode(spec: NodeSpec): ShadeNode {
+ var node = nodes[spec.controller]
+ if (node == null) {
+ node = ShadeNode(spec.controller)
+ nodes[node.controller] = node
+ views[node.view] = node
+ }
+ return node
+ }
+
+ private fun treeToMap(tree: NodeSpec): Map<NodeController, NodeSpec> {
+ val map = mutableMapOf<NodeController, NodeSpec>()
+
+ registerNodes(tree, map)
+
+ return map
+ }
+
+ private fun registerNodes(node: NodeSpec, map: MutableMap<NodeController, NodeSpec>) {
+ if (map.containsKey(node.controller)) {
+ throw RuntimeException("Node ${node.controller.nodeLabel} appears more than once")
+ }
+ map[node.controller] = node
+
+ if (node.children.isNotEmpty()) {
+ for (child in node.children) {
+ registerNodes(child, map)
+ }
+ }
+ }
+}
+
+private class ShadeNode(
+ val controller: NodeController
+) {
+ val view = controller.view
+
+ var parent: ShadeNode? = null
+
+ val label: String
+ get() = controller.nodeLabel
+
+ fun getChildAt(index: Int): View? = controller.getChildAt(index)
+
+ fun getChildCount(): Int = controller.getChildCount()
+
+ fun addChildAt(child: ShadeNode, index: Int) {
+ controller.addChildAt(child.controller, index)
+ }
+
+ fun moveChildTo(child: ShadeNode, index: Int) {
+ controller.moveChildTo(child.controller, index)
+ }
+
+ fun removeChild(child: ShadeNode, isTransfer: Boolean) {
+ controller.removeChild(child.controller, isTransfer)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManagerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt
index 3d561264d367..19e156f572d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewManagerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt
@@ -21,7 +21,7 @@ import com.android.systemui.log.LogLevel
import com.android.systemui.log.dagger.NotificationLog
import javax.inject.Inject
-class NotifViewManagerLogger @Inject constructor(
+class ShadeViewDifferLogger @Inject constructor(
@NotificationLog private val buffer: LogBuffer
) {
fun logDetachingChild(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
new file mode 100644
index 000000000000..201be59d80b4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.render
+
+import com.android.systemui.statusbar.notification.collection.GroupEntry
+import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.ShadeListBuilder
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer
+import java.lang.RuntimeException
+import javax.inject.Inject
+
+/**
+ * Responsible for building and applying the "shade node spec": the list (tree) of things that
+ * currently populate the notification shade.
+ */
+class ShadeViewManager constructor(
+ listContainer: NotificationListContainer,
+ logger: ShadeViewDifferLogger,
+ private val viewBarn: NotifViewBarn
+) {
+ private val rootController = RootNodeController(listContainer)
+ private val viewDiffer = ShadeViewDiffer(rootController, logger)
+
+ fun attach(listBuilder: ShadeListBuilder) {
+ listBuilder.setOnRenderListListener(::onNewNotifTree)
+ }
+
+ private fun onNewNotifTree(tree: List<ListEntry>) {
+ viewDiffer.applySpec(buildTree(tree))
+ }
+
+ private fun buildTree(notifList: List<ListEntry>): NodeSpec {
+ val root = NodeSpecImpl(null, rootController)
+
+ for (entry in notifList) {
+ // TODO: Add section header logic here
+ root.children.add(buildNotifNode(entry, root))
+ }
+
+ return root
+ }
+
+ private fun buildNotifNode(entry: ListEntry, parent: NodeSpec): NodeSpec {
+ return when (entry) {
+ is NotificationEntry -> {
+ NodeSpecImpl(parent, viewBarn.requireView(entry))
+ }
+ is GroupEntry -> {
+ val groupNode = NodeSpecImpl(
+ parent,
+ viewBarn.requireView(checkNotNull(entry.summary)))
+
+ for (childEntry in entry.children) {
+ groupNode.children.add(buildNotifNode(childEntry, groupNode))
+ }
+
+ groupNode
+ }
+ else -> {
+ throw RuntimeException("Unexpected entry: $entry")
+ }
+ }
+ }
+}
+
+class ShadeViewManagerFactory @Inject constructor(
+ private val logger: ShadeViewDifferLogger,
+ private val viewBarn: NotifViewBarn
+) {
+ fun create(listContainer: NotificationListContainer): ShadeViewManager {
+ return ShadeViewManager(listContainer, logger, viewBarn)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java
deleted file mode 100644
index 28c53dc6d9b2..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/AppOpsInfo.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar.notification.row;
-
-import android.app.AppOpsManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.service.notification.StatusBarNotification;
-import android.util.ArraySet;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
-
-/**
- * The guts of a notification revealed when performing a long press.
- */
-public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsContent {
- private static final String TAG = "AppOpsGuts";
-
- private PackageManager mPm;
-
- private String mPkg;
- private String mAppName;
- private int mAppUid;
- private StatusBarNotification mSbn;
- private ArraySet<Integer> mAppOps;
- private MetricsLogger mMetricsLogger;
- private OnSettingsClickListener mOnSettingsClickListener;
- private NotificationGuts mGutsContainer;
- private UiEventLogger mUiEventLogger;
-
- private OnClickListener mOnOk = v -> {
- mGutsContainer.closeControls(v, false);
- };
-
- public AppOpsInfo(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public interface OnSettingsClickListener {
- void onClick(View v, String pkg, int uid, ArraySet<Integer> ops);
- }
-
- public void bindGuts(final PackageManager pm,
- final OnSettingsClickListener onSettingsClick,
- final StatusBarNotification sbn,
- final UiEventLogger uiEventLogger,
- ArraySet<Integer> activeOps) {
- mPkg = sbn.getPackageName();
- mSbn = sbn;
- mPm = pm;
- mAppName = mPkg;
- mOnSettingsClickListener = onSettingsClick;
- mAppOps = activeOps;
- mUiEventLogger = uiEventLogger;
-
- bindHeader();
- bindPrompt();
- bindButtons();
-
- logUiEvent(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_OPEN);
- mMetricsLogger = new MetricsLogger();
- mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, true);
- }
-
- private void bindHeader() {
- // Package name
- Drawable pkgicon = null;
- ApplicationInfo info;
- try {
- info = mPm.getApplicationInfo(mPkg,
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DISABLED_COMPONENTS
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
- | PackageManager.MATCH_DIRECT_BOOT_AWARE);
- if (info != null) {
- mAppUid = mSbn.getUid();
- mAppName = String.valueOf(mPm.getApplicationLabel(info));
- pkgicon = mPm.getApplicationIcon(info);
- }
- } catch (PackageManager.NameNotFoundException e) {
- // app is gone, just show package name and generic icon
- pkgicon = mPm.getDefaultActivityIcon();
- }
- ((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon);
- ((TextView) findViewById(R.id.pkgname)).setText(mAppName);
- }
-
- private void bindPrompt() {
- final TextView prompt = findViewById(R.id.prompt);
- prompt.setText(getPrompt());
- }
-
- private void bindButtons() {
- View settings = findViewById(R.id.settings);
- settings.setOnClickListener((View view) -> {
- mOnSettingsClickListener.onClick(view, mPkg, mAppUid, mAppOps);
- });
- TextView ok = findViewById(R.id.ok);
- ok.setOnClickListener(mOnOk);
- ok.setAccessibilityDelegate(mGutsContainer.getAccessibilityDelegate());
- }
-
- private String getPrompt() {
- if (mAppOps == null || mAppOps.size() == 0) {
- return "";
- } else if (mAppOps.size() == 1) {
- if (mAppOps.contains(AppOpsManager.OP_CAMERA)) {
- return mContext.getString(R.string.appops_camera);
- } else if (mAppOps.contains(AppOpsManager.OP_RECORD_AUDIO)) {
- return mContext.getString(R.string.appops_microphone);
- } else {
- return mContext.getString(R.string.appops_overlay);
- }
- } else if (mAppOps.size() == 2) {
- if (mAppOps.contains(AppOpsManager.OP_CAMERA)) {
- if (mAppOps.contains(AppOpsManager.OP_RECORD_AUDIO)) {
- return mContext.getString(R.string.appops_camera_mic);
- } else {
- return mContext.getString(R.string.appops_camera_overlay);
- }
- } else {
- return mContext.getString(R.string.appops_mic_overlay);
- }
- } else {
- return mContext.getString(R.string.appops_camera_mic_overlay);
- }
- }
-
- @Override
- public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
- super.onInitializeAccessibilityEvent(event);
- if (mGutsContainer != null &&
- event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
- if (mGutsContainer.isExposed()) {
- event.getText().add(mContext.getString(
- R.string.notification_channel_controls_opened_accessibility, mAppName));
- } else {
- event.getText().add(mContext.getString(
- R.string.notification_channel_controls_closed_accessibility, mAppName));
- }
- }
- }
-
- @Override
- public void setGutsParent(NotificationGuts guts) {
- mGutsContainer = guts;
- }
-
- @Override
- public boolean willBeRemoved() {
- return false;
- }
-
- @Override
- public boolean shouldBeSaved() {
- return false;
- }
-
- @Override
- public boolean needsFalsingProtection() {
- return false;
- }
-
- @Override
- public View getContentView() {
- return this;
- }
-
- @Override
- public boolean handleCloseControls(boolean save, boolean force) {
- logUiEvent(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_CLOSE);
- if (mMetricsLogger != null) {
- mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, false);
- }
- return false;
- }
-
- @Override
- public int getActualHeight() {
- return getHeight();
- }
-
- private void logUiEvent(NotificationAppOpsEvent event) {
- if (mSbn != null) {
- mUiEventLogger.logWithInstanceId(event,
- mSbn.getUid(), mSbn.getPackageName(), mSbn.getInstanceId());
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 22d0357b14c2..d7fa54f0091d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -239,7 +239,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private boolean mShowNoBackground;
private ExpandableNotificationRow mNotificationParent;
private OnExpandClickListener mOnExpandClickListener;
- private View.OnClickListener mOnAppOpsClickListener;
+ private View.OnClickListener mOnAppClickListener;
private View.OnClickListener mOnFeedbackClickListener;
// Listener will be called when receiving a long click event.
@@ -1139,7 +1139,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
items.add(NotificationMenuRow.createPartialConversationItem(mContext));
items.add(NotificationMenuRow.createInfoItem(mContext));
items.add(NotificationMenuRow.createSnoozeItem(mContext));
- items.add(NotificationMenuRow.createAppOpsItem(mContext));
mMenuRow.setMenuItems(items);
}
if (existed) {
@@ -1598,7 +1597,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
RowContentBindStage rowContentBindStage,
OnExpandClickListener onExpandClickListener,
NotificationMediaManager notificationMediaManager,
- CoordinateOnClickListener onAppOpsClickListener,
CoordinateOnClickListener onFeedbackClickListener,
FalsingManager falsingManager,
StatusBarStateController statusBarStateController,
@@ -1619,7 +1617,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mRowContentBindStage = rowContentBindStage;
mOnExpandClickListener = onExpandClickListener;
mMediaManager = notificationMediaManager;
- setAppOpsOnClickListener(onAppOpsClickListener);
setOnFeedbackClickListener(onFeedbackClickListener);
mFalsingManager = falsingManager;
mStatusbarStateController = statusBarStateController;
@@ -1677,14 +1674,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
requestLayout();
}
- public void showAppOpsIcons(ArraySet<Integer> activeOps) {
- if (mIsSummaryWithChildren) {
- mChildrenContainer.showAppOpsIcons(activeOps);
- }
- mPrivateLayout.showAppOpsIcons(activeOps);
- mPublicLayout.showAppOpsIcons(activeOps);
- }
-
public void showFeedbackIcon(boolean show) {
if (mIsSummaryWithChildren) {
mChildrenContainer.showFeedbackIcon(show);
@@ -1721,24 +1710,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mPublicLayout.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
}
- public View.OnClickListener getAppOpsOnClickListener() {
- return mOnAppOpsClickListener;
- }
-
- void setAppOpsOnClickListener(CoordinateOnClickListener l) {
- mOnAppOpsClickListener = v -> {
- createMenu();
- NotificationMenuRowPlugin provider = getProvider();
- if (provider == null) {
- return;
- }
- MenuItem menuItem = provider.getAppOpsMenuItem(mContext);
- if (menuItem != null) {
- l.onClick(this, v.getWidth() / 2, v.getHeight() / 2, menuItem);
- }
- };
- }
-
public View.OnClickListener getFeedbackOnClickListener() {
return mOnFeedbackClickListener;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 86a3271c4eac..690dce915cf3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -22,21 +22,27 @@ import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENAB
import android.view.View;
import android.view.ViewGroup;
+import androidx.annotation.NonNull;
+
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.notification.collection.render.NodeController;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.dagger.AppName;
import com.android.systemui.statusbar.notification.row.dagger.NotificationKey;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.time.SystemClock;
+import java.util.List;
+
import javax.inject.Inject;
import javax.inject.Named;
@@ -44,8 +50,9 @@ import javax.inject.Named;
* Controller for {@link ExpandableNotificationRow}.
*/
@NotificationRowScope
-public class ExpandableNotificationRowController {
+public class ExpandableNotificationRowController implements NodeController {
private final ExpandableNotificationRow mView;
+ private final NotificationListContainer mListContainer;
private final ActivatableNotificationViewController mActivatableNotificationViewController;
private final NotificationMediaManager mMediaManager;
private final PluginManager mPluginManager;
@@ -62,7 +69,6 @@ public class ExpandableNotificationRowController {
private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger =
this::logNotificationExpansion;
- private final ExpandableNotificationRow.CoordinateOnClickListener mOnAppOpsClickListener;
private final ExpandableNotificationRow.CoordinateOnClickListener mOnFeedbackClickListener;
private final NotificationGutsManager mNotificationGutsManager;
private final OnDismissCallback mOnDismissCallback;
@@ -72,6 +78,7 @@ public class ExpandableNotificationRowController {
@Inject
public ExpandableNotificationRowController(ExpandableNotificationRow view,
+ NotificationListContainer listContainer,
ActivatableNotificationViewController activatableNotificationViewController,
NotificationMediaManager mediaManager, PluginManager pluginManager,
SystemClock clock, @AppName String appName, @NotificationKey String notificationKey,
@@ -86,6 +93,7 @@ public class ExpandableNotificationRowController {
OnDismissCallback onDismissCallback, FalsingManager falsingManager,
PeopleNotificationIdentifier peopleNotificationIdentifier) {
mView = view;
+ mListContainer = listContainer;
mActivatableNotificationViewController = activatableNotificationViewController;
mMediaManager = mediaManager;
mPluginManager = pluginManager;
@@ -101,7 +109,6 @@ public class ExpandableNotificationRowController {
mStatusBarStateController = statusBarStateController;
mNotificationGutsManager = notificationGutsManager;
mOnDismissCallback = onDismissCallback;
- mOnAppOpsClickListener = mNotificationGutsManager::openGuts;
mOnFeedbackClickListener = mNotificationGutsManager::openGuts;
mAllowLongPress = allowLongPress;
mFalsingManager = falsingManager;
@@ -123,7 +130,6 @@ public class ExpandableNotificationRowController {
mRowContentBindStage,
mOnExpandClickListener,
mMediaManager,
- mOnAppOpsClickListener,
mOnFeedbackClickListener,
mFalsingManager,
mStatusBarStateController,
@@ -162,4 +168,52 @@ public class ExpandableNotificationRowController {
private void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
mNotificationLogger.onExpansionChanged(key, userAction, expanded);
}
+
+ @Override
+ @NonNull
+ public String getNodeLabel() {
+ return mView.getEntry().getKey();
+ }
+
+ @Override
+ @NonNull
+ public View getView() {
+ return mView;
+ }
+
+ @Override
+ public View getChildAt(int index) {
+ return mView.getChildNotificationAt(index);
+ }
+
+ @Override
+ public void addChildAt(NodeController child, int index) {
+ ExpandableNotificationRow childView = (ExpandableNotificationRow) child.getView();
+
+ mView.addChildNotification((ExpandableNotificationRow) child.getView());
+ mListContainer.notifyGroupChildAdded(childView);
+ }
+
+ @Override
+ public void moveChildTo(NodeController child, int index) {
+ ExpandableNotificationRow childView = (ExpandableNotificationRow) child.getView();
+ mView.removeChildNotification(childView);
+ mView.addChildNotification(childView, index);
+ }
+
+ @Override
+ public void removeChild(NodeController child, boolean isTransfer) {
+ ExpandableNotificationRow childView = (ExpandableNotificationRow) child.getView();
+
+ mView.removeChildNotification(childView);
+ if (!isTransfer) {
+ mListContainer.notifyGroupChildRemoved(childView, mView);
+ }
+ }
+
+ @Override
+ public int getChildCount() {
+ final List<ExpandableNotificationRow> mChildren = mView.getAttachedChildren();
+ return mChildren != null ? mChildren.size() : 0;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 2986b9b75b98..c7e44c5e8e0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -1568,18 +1568,6 @@ public class NotificationContentView extends FrameLayout {
return header;
}
- public void showAppOpsIcons(ArraySet<Integer> activeOps) {
- if (mContractedChild != null) {
- mContractedWrapper.showAppOpsIcons(activeOps);
- }
- if (mExpandedChild != null) {
- mExpandedWrapper.showAppOpsIcons(activeOps);
- }
- if (mHeadsUpChild != null) {
- mHeadsUpWrapper.showAppOpsIcons(activeOps);
- }
- }
-
public void showFeedbackIcon(boolean show) {
if (mContractedChild != null) {
mContractedWrapper.showFeedbackIcon(show);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 729b131ac553..05d44f6eb406 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -268,8 +268,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
try {
if (gutsView instanceof NotificationSnooze) {
initializeSnoozeView(row, (NotificationSnooze) gutsView);
- } else if (gutsView instanceof AppOpsInfo) {
- initializeAppOpsInfo(row, (AppOpsInfo) gutsView);
} else if (gutsView instanceof NotificationInfo) {
initializeNotificationInfo(row, (NotificationInfo) gutsView);
} else if (gutsView instanceof NotificationConversationInfo) {
@@ -309,36 +307,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
}
/**
- * Sets up the {@link AppOpsInfo} inside the notification row's guts.
- *
- * @param row view to set up the guts for
- * @param appOpsInfoView view to set up/bind within {@code row}
- */
- private void initializeAppOpsInfo(
- final ExpandableNotificationRow row,
- AppOpsInfo appOpsInfoView) {
- NotificationGuts guts = row.getGuts();
- StatusBarNotification sbn = row.getEntry().getSbn();
- UserHandle userHandle = sbn.getUser();
- PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext,
- userHandle.getIdentifier());
-
- AppOpsInfo.OnSettingsClickListener onSettingsClick =
- (View v, String pkg, int uid, ArraySet<Integer> ops) -> {
- mUiEventLogger.logWithInstanceId(
- NotificationAppOpsEvent.NOTIFICATION_APP_OPS_SETTINGS_CLICK,
- sbn.getUid(), sbn.getPackageName(), sbn.getInstanceId());
- mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_OPS_GUTS_SETTINGS);
- guts.resetFalsingCheck();
- startAppOpsSettingsActivity(pkg, uid, ops, row);
- };
- if (!row.getEntry().mActiveAppOps.isEmpty()) {
- appOpsInfoView.bindGuts(pmUser, onSettingsClick, sbn, mUiEventLogger,
- row.getEntry().mActiveAppOps);
- }
- }
-
- /**
* Sets up the {@link FeedbackInfo} inside the notification row's guts.
*
* @param row view to set up the guts for
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index d264af94947d..205cecc92e55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -76,7 +76,6 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
private Context mContext;
private FrameLayout mMenuContainer;
private NotificationMenuItem mInfoItem;
- private MenuItem mAppOpsItem;
private MenuItem mFeedbackItem;
private MenuItem mSnoozeItem;
private ArrayList<MenuItem> mLeftMenuItems;
@@ -138,11 +137,6 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
}
@Override
- public MenuItem getAppOpsMenuItem(Context context) {
- return mAppOpsItem;
- }
-
- @Override
public MenuItem getFeedbackMenuItem(Context context) {
return mFeedbackItem;
}
@@ -264,7 +258,6 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
// Only show snooze for non-foreground notifications, and if the setting is on
mSnoozeItem = createSnoozeItem(mContext);
}
- mAppOpsItem = createAppOpsItem(mContext);
mFeedbackItem = createFeedbackItem(mContext);
NotificationEntry entry = mParent.getEntry();
int personNotifType = mPeopleNotificationIdentifier
@@ -281,7 +274,6 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
mRightMenuItems.add(mSnoozeItem);
}
mRightMenuItems.add(mInfoItem);
- mRightMenuItems.add(mAppOpsItem);
mRightMenuItems.add(mFeedbackItem);
mLeftMenuItems.addAll(mRightMenuItems);
@@ -690,14 +682,6 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
R.drawable.ic_settings);
}
- static MenuItem createAppOpsItem(Context context) {
- AppOpsInfo appOpsContent = (AppOpsInfo) LayoutInflater.from(context).inflate(
- R.layout.app_ops_info, null, false);
- MenuItem info = new NotificationMenuItem(context, null, appOpsContent,
- -1 /*don't show in slow swipe menu */);
- return info;
- }
-
static MenuItem createFeedbackItem(Context context) {
FeedbackInfo feedbackContent = (FeedbackInfo) LayoutInflater.from(context).inflate(
R.layout.feedback_info, null, false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
index 28ddf5971bcb..becc9a772b28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
@@ -25,6 +25,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.StatusBar;
import dagger.Binds;
@@ -55,6 +56,8 @@ public interface ExpandableNotificationRowComponent {
Builder notificationEntry(NotificationEntry entry);
@BindsInstance
Builder onExpandClickListener(ExpandableNotificationRow.OnExpandClickListener presenter);
+ @BindsInstance
+ Builder listContainer(NotificationListContainer listContainer);
ExpandableNotificationRowComponent build();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index 46517711a0dc..3f5867477f16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.row.wrapper;
import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
-import android.app.AppOpsManager;
import android.app.Notification;
import android.content.Context;
import android.util.ArraySet;
@@ -64,10 +63,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
private TextView mHeaderText;
private TextView mAppNameText;
private ImageView mWorkProfileImage;
- private View mCameraIcon;
- private View mMicIcon;
- private View mOverlayIcon;
- private View mAppOps;
private View mAudiblyAlertedIcon;
private FrameLayout mIconContainer;
private View mFeedbackIcon;
@@ -109,7 +104,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
}
}, TRANSFORMING_VIEW_TITLE);
resolveHeaderViews();
- addAppOpsOnClickListener(row);
addFeedbackOnClickListener(row);
}
@@ -121,10 +115,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button);
mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
- mCameraIcon = mView.findViewById(com.android.internal.R.id.camera);
- mMicIcon = mView.findViewById(com.android.internal.R.id.mic);
- mOverlayIcon = mView.findViewById(com.android.internal.R.id.overlay);
- mAppOps = mView.findViewById(com.android.internal.R.id.app_ops);
mAudiblyAlertedIcon = mView.findViewById(com.android.internal.R.id.alerted_icon);
mFeedbackIcon = mView.findViewById(com.android.internal.R.id.feedback);
if (mNotificationHeader != null) {
@@ -133,38 +123,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
}
}
- private void addAppOpsOnClickListener(ExpandableNotificationRow row) {
- View.OnClickListener listener = row.getAppOpsOnClickListener();
- if (mNotificationHeader != null) {
- mNotificationHeader.setAppOpsOnClickListener(listener);
- }
- if (mAppOps != null) {
- mAppOps.setOnClickListener(listener);
- }
- }
-
- /**
- * Shows or hides 'app op in use' icons based on app usage.
- */
- @Override
- public void showAppOpsIcons(ArraySet<Integer> appOps) {
- if (appOps == null) {
- return;
- }
- if (mOverlayIcon != null) {
- mOverlayIcon.setVisibility(appOps.contains(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
- ? View.VISIBLE : View.GONE);
- }
- if (mCameraIcon != null) {
- mCameraIcon.setVisibility(appOps.contains(AppOpsManager.OP_CAMERA)
- ? View.VISIBLE : View.GONE);
- }
- if (mMicIcon != null) {
- mMicIcon.setVisibility(appOps.contains(AppOpsManager.OP_RECORD_AUDIO)
- ? View.VISIBLE : View.GONE);
- }
- }
-
private void addFeedbackOnClickListener(ExpandableNotificationRow row) {
View.OnClickListener listener = row.getFeedbackOnClickListener();
if (mNotificationHeader != null) {
@@ -304,15 +262,6 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE,
mHeaderText);
}
- if (mCameraIcon != null) {
- mTransformationHelper.addViewTransformingToSimilar(mCameraIcon);
- }
- if (mMicIcon != null) {
- mTransformationHelper.addViewTransformingToSimilar(mMicIcon);
- }
- if (mOverlayIcon != null) {
- mTransformationHelper.addViewTransformingToSimilar(mOverlayIcon);
- }
if (mAudiblyAlertedIcon != null) {
mTransformationHelper.addViewTransformingToSimilar(mAudiblyAlertedIcon);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index 605fbc0f6125..42f5e389d5a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -97,14 +97,6 @@ public abstract class NotificationViewWrapper implements TransformableView {
}
/**
- * Show a set of app opp icons in the layout.
- *
- * @param appOps which app ops to show
- */
- public void showAppOpsIcons(ArraySet<Integer> appOps) {
- }
-
- /**
* Shows or hides feedback icon.
*/
public void showFeedbackIcon(boolean show) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 93c2377ccfae..7e4266c7cd28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -1303,20 +1303,6 @@ public class NotificationChildrenContainer extends ViewGroup {
}
/**
- * Show a set of app opp icons in the layout.
- *
- * @param appOps which app ops to show
- */
- public void showAppOpsIcons(ArraySet<Integer> appOps) {
- if (mNotificationHeaderWrapper != null) {
- mNotificationHeaderWrapper.showAppOpsIcons(appOps);
- }
- if (mNotificationHeaderWrapperLowPriority != null) {
- mNotificationHeaderWrapperLowPriority.showAppOpsIcons(appOps);
- }
- }
-
- /**
* Shows or hides feedback icon.
*/
public void showFeedbackIcon(boolean show) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 2ff67abd6377..d2f8a39cc8fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -180,8 +180,7 @@ import javax.inject.Named;
* A layout which handles a dynamic amount of notifications and presents them in a scrollable stack.
*/
public class NotificationStackScrollLayout extends ViewGroup implements ScrollAdapter,
- NotificationListContainer, ConfigurationListener, Dumpable,
- DynamicPrivacyController.Listener {
+ ConfigurationListener, Dumpable, DynamicPrivacyController.Listener {
public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
private static final String TAG = "StackScroller";
@@ -213,6 +212,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private float mExpandedHeight;
private int mOwnScrollY;
+
private View mScrollAnchorView;
private int mScrollAnchorViewY;
private int mMaxLayoutHeight;
@@ -545,6 +545,19 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
updateDecorViews(useDarkText);
};
+ private final ExpandableView.OnHeightChangedListener mOnChildHeightChangedListener =
+ new ExpandableView.OnHeightChangedListener() {
+ @Override
+ public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
+ onChildHeightChanged(view, needsAnimation);
+ }
+
+ @Override
+ public void onReset(ExpandableView view) {
+ onChildHeightReset(view);
+ }
+ };
+
@Inject
public NotificationStackScrollLayout(
@Named(VIEW_CONTEXT) Context context,
@@ -576,7 +589,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mLockscreenUserManager = notificationLockscreenUserManager;
mNotificationGutsManager = notificationGutsManager;
mHeadsUpManager = headsUpManager;
- mHeadsUpManager.addListener(mRoundnessManager);
mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed);
mKeyguardBypassController = keyguardBypassController;
mFalsingManager = falsingManager;
@@ -608,9 +620,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
res.getBoolean(R.bool.config_drawNotificationBackground);
mFadeNotificationsOnDismiss =
res.getBoolean(R.bool.config_fadeNotificationsOnDismiss);
- mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated);
- mRoundnessManager.setOnRoundingChangedCallback(this::invalidate);
- addOnExpandedHeightChangedListener(mRoundnessManager::setExpanded);
mLockscreenUserManager.addUserChangedListener(mLockscreenUserChangeListener);
setOutlineProvider(mOutlineProvider);
@@ -637,13 +646,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
tunerService.addTunable((key, newValue) -> {
if (key.equals(HIGH_PRIORITY)) {
mHighPriorityBeforeSpeedBump = "1".equals(newValue);
- } else if (key.equals(Settings.Secure.NOTIFICATION_DISMISS_RTL)) {
- updateDismissRtlSetting("1".equals(newValue));
- } else if (key.equals(Settings.Secure.NOTIFICATION_HISTORY_ENABLED)) {
- updateFooter();
}
- }, HIGH_PRIORITY, Settings.Secure.NOTIFICATION_DISMISS_RTL,
- Settings.Secure.NOTIFICATION_HISTORY_ENABLED);
+ }, HIGH_PRIORITY);
mFeatureFlags = featureFlags;
mNotifPipeline = notifPipeline;
@@ -693,7 +697,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
}
- private void updateDismissRtlSetting(boolean dismissRtl) {
+ void updateDismissRtlSetting(boolean dismissRtl) {
mDismissRtl = dismissRtl;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
@@ -834,7 +838,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
Dependency.get(ConfigurationController.class).removeCallback(this);
}
- @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public NotificationSwipeActionHelper getSwipeActionHelper() {
return mSwipeHelper;
@@ -1150,14 +1153,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mNoAmbient = noAmbient;
}
- @Override
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void setChildLocationsChangedListener(
NotificationLogger.OnChildLocationsChangedListener listener) {
mListener = listener;
}
- @Override
+ public void setScrollAnchorView(View scrollAnchorView) {
+ mScrollAnchorView = scrollAnchorView;
+ }
+
@ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM)
public boolean isInVisibleLocation(NotificationEntry entry) {
ExpandableNotificationRow row = entry.getRow();
@@ -1856,7 +1861,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
}
- @Override
@ShadeViewRefactor(RefactorComponent.ADAPTER)
public ViewGroup getViewParentForNotification(NotificationEntry entry) {
return this;
@@ -2546,7 +2550,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
previous);
}
- @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public boolean hasPulsingNotifications() {
return mPulsing;
@@ -3050,7 +3053,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- @Override
public void cleanUpViewStateForEntry(NotificationEntry entry) {
View child = entry.getRow();
if (child == mSwipeHelper.getTranslatingParentView()) {
@@ -3317,7 +3319,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void onViewAdded(View child) {
super.onViewAdded(child);
- onViewAddedInternal((ExpandableView) child);
+ if (child instanceof ExpandableView) {
+ onViewAddedInternal((ExpandableView) child);
+ }
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -3350,9 +3354,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- private void onViewAddedInternal(ExpandableView child) {
+ void onViewAddedInternal(ExpandableView child) {
+ child.setOnHeightChangedListener(mOnChildHeightChangedListener);
updateHideSensitiveForChild(child);
- child.setOnHeightChangedListener(this);
generateAddAnimation(child, false /* fromMoreCard */);
updateAnimationState(child);
updateChronometerForChild(child);
@@ -3374,18 +3378,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
child.setHideSensitiveForIntrinsicHeight(mAmbientState.isHideSensitive());
}
- @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void notifyGroupChildRemoved(ExpandableView row, ViewGroup childrenContainer) {
onViewRemovedInternal(row, childrenContainer);
}
- @Override
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void notifyGroupChildAdded(ExpandableView row) {
- onViewAddedInternal(row);
- }
-
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void setAnimationsEnabled(boolean animationsEnabled) {
mAnimationsEnabled = animationsEnabled;
@@ -3410,33 +3407,29 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private void updateAnimationState(View child) {
+ void updateAnimationState(View child) {
updateAnimationState((mAnimationsEnabled || hasPulsingNotifications())
&& (mIsExpanded || isPinnedHeadsUp(child)), child);
}
- @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setExpandingNotification(ExpandableNotificationRow row) {
+ void setExpandingNotification(ExpandableNotificationRow row) {
mAmbientState.setExpandingNotification(row);
requestChildrenUpdate();
}
- @Override
@ShadeViewRefactor(RefactorComponent.ADAPTER)
- public void bindRow(ExpandableNotificationRow row) {
+ void bindRow(ExpandableNotificationRow row) {
row.setHeadsUpAnimatingAwayListener(animatingAway -> {
mRoundnessManager.onHeadsupAnimatingAwayChanged(row, animatingAway);
mHeadsUpAppearanceController.updateHeader(row.getEntry());
});
}
- @Override
public boolean containsView(View v) {
return v.getParent() == this;
}
- @Override
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void applyExpandAnimationParams(ExpandAnimationParameters params) {
mAmbientState.setExpandAnimationTopChange(params == null ? 0 : params.getTopChange());
@@ -3452,12 +3445,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- public boolean isAddOrRemoveAnimationPending() {
+ boolean isAddOrRemoveAnimationPending() {
return mNeedsAnimation
&& (!mChildrenToAddAnimated.isEmpty() || !mChildrenToRemoveAnimated.isEmpty());
}
- @Override
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void generateAddAnimation(ExpandableView child, boolean fromMoreCard) {
if (mIsExpanded && mAnimationsEnabled && !mChangePositionInProgress && !isFullyHidden()) {
@@ -3475,7 +3467,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
}
- @Override
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void changeViewPosition(ExpandableView child, int newIndex) {
Assert.isMainThread();
@@ -4471,12 +4462,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- public int getEmptyBottomMargin() {
+ int getEmptyBottomMargin() {
return Math.max(mMaxLayoutHeight - mContentHeight, 0);
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void checkSnoozeLeavebehind() {
+ void checkSnoozeLeavebehind() {
if (mCheckForLeavebehind) {
mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
@@ -4486,19 +4477,19 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void resetCheckSnoozeLeavebehind() {
+ void resetCheckSnoozeLeavebehind() {
mCheckForLeavebehind = true;
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- public void onExpansionStarted() {
+ void onExpansionStarted() {
mIsExpansionChanging = true;
mAmbientState.setExpansionChanging(true);
checkSnoozeLeavebehind();
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- public void onExpansionStopped() {
+ void onExpansionStopped() {
mIsExpansionChanging = false;
resetCheckSnoozeLeavebehind();
mAmbientState.setExpansionChanging(false);
@@ -4547,20 +4538,20 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- public void onPanelTrackingStarted() {
+ void onPanelTrackingStarted() {
mPanelTracking = true;
mAmbientState.setPanelTracking(true);
resetExposedMenuView(true /* animate */, true /* force */);
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- public void onPanelTrackingStopped() {
+ void onPanelTrackingStopped() {
mPanelTracking = false;
mAmbientState.setPanelTracking(false);
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- public void resetScrollPosition() {
+ void resetScrollPosition() {
mScroller.abortAnimation();
if (ANCHOR_SCROLLING) {
// TODO: once we're recycling this will need to modify the adapter position instead
@@ -4601,15 +4592,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- private void updateChronometerForChild(View child) {
+ void updateChronometerForChild(View child) {
if (child instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
row.setChronometerRunning(mIsExpanded);
}
}
- @Override
- public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
+ void onChildHeightChanged(ExpandableView view, boolean needsAnimation) {
updateContentHeight();
updateScrollPositionOnExpandInBottom(view);
clampScrollPosition();
@@ -4632,8 +4622,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
requestChildrenUpdate();
}
- @Override
- public void onReset(ExpandableView view) {
+ void onChildHeightReset(ExpandableView view) {
updateAnimationState(view);
updateChronometerForChild(view);
}
@@ -4674,13 +4663,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setOnHeightChangedListener(
+ void setOnHeightChangedListener(
ExpandableView.OnHeightChangedListener onHeightChangedListener) {
this.mOnHeightChangedListener = onHeightChangedListener;
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- public void onChildAnimationFinished() {
+ void onChildAnimationFinished() {
setAnimationRunning(false);
requestChildrenUpdate();
runAnimationFinishedRunnables();
@@ -4724,7 +4713,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
* See {@link AmbientState#setDimmed}.
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setDimmed(boolean dimmed, boolean animate) {
+ void setDimmed(boolean dimmed, boolean animate) {
dimmed &= onKeyguard();
mAmbientState.setDimmed(dimmed);
if (animate && mAnimationsEnabled) {
@@ -4789,7 +4778,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
* See {@link AmbientState#setActivatedChild}.
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setActivatedChild(ActivatableNotificationView activatedChild) {
+ void setActivatedChild(ActivatableNotificationView activatedChild) {
mAmbientState.setActivatedChild(activatedChild);
if (mAnimationsEnabled) {
mActivateNeedsAnimation = true;
@@ -4865,7 +4854,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
* @param lightTheme True if light theme should be used.
*/
@ShadeViewRefactor(RefactorComponent.DECORATOR)
- public void updateDecorViews(boolean lightTheme) {
+ private void updateDecorViews(boolean lightTheme) {
if (lightTheme == mUsingLightTheme) {
return;
}
@@ -4880,7 +4869,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void goToFullShade(long delay) {
+ void goToFullShade(long delay) {
mGoToFullShadeNeedsAnimation = true;
mGoToFullShadeDelay = delay;
mNeedsAnimation = true;
@@ -4893,13 +4882,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- public void setIntrinsicPadding(int intrinsicPadding) {
+ void setIntrinsicPadding(int intrinsicPadding) {
mIntrinsicPadding = intrinsicPadding;
mAmbientState.setIntrinsicPadding(intrinsicPadding);
}
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- public int getIntrinsicPadding() {
+ int getIntrinsicPadding() {
return mIntrinsicPadding;
}
@@ -4933,7 +4922,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
* animation curve.
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setHideAmount(float linearHideAmount, float interpolatedHideAmount) {
+ void setHideAmount(float linearHideAmount, float interpolatedHideAmount) {
mLinearHideAmount = linearHideAmount;
mInterpolatedHideAmount = interpolatedHideAmount;
boolean wasFullyHidden = mAmbientState.isFullyHidden();
@@ -4975,7 +4964,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- public void notifyHideAnimationStart(boolean hide) {
+ void notifyHideAnimationStart(boolean hide) {
// We only swap the scaling factor if we're fully hidden or fully awake to avoid
// interpolation issues when playing with the power button.
if (mInterpolatedHideAmount == 0 || mInterpolatedHideAmount == 1) {
@@ -5003,7 +4992,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setFooterView(@NonNull FooterView footerView) {
+ void setFooterView(@NonNull FooterView footerView) {
int index = -1;
if (mFooterView != null) {
index = indexOfChild(mFooterView);
@@ -5014,7 +5003,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setEmptyShadeView(EmptyShadeView emptyShadeView) {
+ void setEmptyShadeView(EmptyShadeView emptyShadeView) {
int index = -1;
if (mEmptyShadeView != null) {
index = indexOfChild(mEmptyShadeView);
@@ -5025,7 +5014,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void updateEmptyShadeView(boolean visible) {
+ void updateEmptyShadeView(boolean visible) {
mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
int oldTextRes = mEmptyShadeView.getTextResource();
@@ -5209,33 +5198,28 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
}
- @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public int getContainerChildCount() {
return getChildCount();
}
- @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public View getContainerChildAt(int i) {
return getChildAt(i);
}
- @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void removeContainerView(View v) {
Assert.isMainThread();
removeView(v);
}
- @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void addContainerView(View v) {
Assert.isMainThread();
addView(v);
}
- @Override
public void addContainerViewAt(View v, int index) {
Assert.isMainThread();
addView(v, index);
@@ -5277,7 +5261,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
requestChildrenUpdate();
}
- @Override
public void setWillExpand(boolean willExpand) {
mWillExpand = willExpand;
}
@@ -5742,7 +5725,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
}
- @Override
public void setNotificationActivityStarter(
NotificationActivityStarter notificationActivityStarter) {
mNotificationActivityStarter = notificationActivityStarter;
@@ -5900,6 +5882,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
public void setController(
NotificationStackScrollLayoutController notificationStackScrollLayoutController) {
mController = notificationStackScrollLayoutController;
+ mController.getNoticationRoundessManager().setAnimatedChildren(mChildrenToAddAnimated);
}
public NotificationStackScrollLayoutController getController() {
@@ -6000,7 +5983,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
}
- @Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void resetExposedMenuView(boolean animate, boolean force) {
mSwipeHelper.resetExposedMenuView(animate, force);
@@ -6752,7 +6734,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
changedRow.setChildrenExpanded(expanded, animated);
if (!mGroupExpandedForMeasure) {
- onHeightChanged(changedRow, false /* needsAnimation */);
+ onChildHeightChanged(changedRow, false /* needsAnimation */);
}
runAfterAnimationFinished(new Runnable() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 8150593e69fd..53d3b7586f7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -17,22 +17,29 @@
package com.android.systemui.statusbar.notification.stack;
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
import android.graphics.PointF;
+import android.provider.Settings;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.FrameLayout;
+import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.RemoteInputController;
+import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
+import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
@@ -40,6 +47,7 @@ import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.tuner.TunerService;
import java.util.function.BiConsumer;
@@ -53,14 +61,25 @@ import javax.inject.Named;
public class NotificationStackScrollLayoutController {
private final boolean mAllowLongPress;
private final NotificationGutsManager mNotificationGutsManager;
+ private final HeadsUpManagerPhone mHeadsUpManager;
+ private final NotificationRoundnessManager mNotificationRoundnessManager;
+ private final TunerService mTunerService;
+ private final NotificationListContainerImpl mNotificationListContainer =
+ new NotificationListContainerImpl();
private NotificationStackScrollLayout mView;
@Inject
public NotificationStackScrollLayoutController(
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
- NotificationGutsManager notificationGutsManager) {
+ NotificationGutsManager notificationGutsManager,
+ HeadsUpManagerPhone headsUpManager,
+ NotificationRoundnessManager notificationRoundnessManager,
+ TunerService tunerService) {
mAllowLongPress = allowLongPress;
mNotificationGutsManager = notificationGutsManager;
+ mHeadsUpManager = headsUpManager;
+ mNotificationRoundnessManager = notificationRoundnessManager;
+ mTunerService = tunerService;
}
public void attach(NotificationStackScrollLayout view) {
@@ -70,6 +89,17 @@ public class NotificationStackScrollLayoutController {
if (mAllowLongPress) {
mView.setLongPressListener(mNotificationGutsManager::openGuts);
}
+
+ mHeadsUpManager.addListener(mNotificationRoundnessManager); // TODO: why is this here?
+
+ mNotificationRoundnessManager.setOnRoundingChangedCallback(mView::invalidate);
+ mView.addOnExpandedHeightChangedListener(mNotificationRoundnessManager::setExpanded);
+
+ mTunerService.addTunable((key, newValue) -> {
+ if (key.equals(Settings.Secure.NOTIFICATION_DISMISS_RTL)) {
+ mView.updateDismissRtlSetting("1".equals(newValue));
+ }
+ }, HIGH_PRIORITY, Settings.Secure.NOTIFICATION_DISMISS_RTL);
}
public void addOnExpandedHeightChangedListener(BiConsumer<Float, Float> listener) {
@@ -457,10 +487,6 @@ public class NotificationStackScrollLayoutController {
mView.onUpdateRowStates();
}
- public boolean hasPulsingNotifications() {
- return mView.hasPulsingNotifications();
- }
-
public ActivatableNotificationView getActivatedChild() {
return mView.getActivatedChild();
}
@@ -537,4 +563,151 @@ public class NotificationStackScrollLayoutController {
public float calculateGapHeight(ExpandableView previousView, ExpandableView child, int count) {
return mView.calculateGapHeight(previousView, child, count);
}
+
+ public NotificationRoundnessManager getNoticationRoundessManager() {
+ return mNotificationRoundnessManager;
+ }
+
+ public NotificationListContainer getNotificationListContainer() {
+ return mNotificationListContainer;
+ }
+
+ private class NotificationListContainerImpl implements NotificationListContainer {
+ @Override
+ public void setChildTransferInProgress(boolean childTransferInProgress) {
+ mView.setChildTransferInProgress(childTransferInProgress);
+ }
+
+ @Override
+ public void changeViewPosition(ExpandableView child, int newIndex) {
+ mView.changeViewPosition(child, newIndex);
+ }
+
+ @Override
+ public void notifyGroupChildAdded(ExpandableView row) {
+ mView.onViewAddedInternal(row);
+ }
+
+ @Override
+ public void notifyGroupChildRemoved(ExpandableView row, ViewGroup childrenContainer) {
+ mView.notifyGroupChildRemoved(row, childrenContainer);
+ }
+
+ @Override
+ public void generateAddAnimation(ExpandableView child, boolean fromMoreCard) {
+ mView.generateAddAnimation(child, fromMoreCard);
+ }
+
+ @Override
+ public void generateChildOrderChangedEvent() {
+ mView.generateChildOrderChangedEvent();
+ }
+
+ @Override
+ public int getContainerChildCount() {
+ return mView.getContainerChildCount();
+ }
+
+ @Override
+ public void setNotificationActivityStarter(
+ NotificationActivityStarter notificationActivityStarter) {
+ mView.setNotificationActivityStarter(notificationActivityStarter);
+ }
+
+ @Override
+ public View getContainerChildAt(int i) {
+ return mView.getContainerChildAt(i);
+ }
+
+ @Override
+ public void removeContainerView(View v) {
+ mView.removeContainerView(v);
+ }
+
+ @Override
+ public void addContainerView(View v) {
+ mView.addContainerView(v);
+ }
+
+ @Override
+ public void addContainerViewAt(View v, int index) {
+ mView.addContainerViewAt(v, index);
+ }
+
+ @Override
+ public void setMaxDisplayedNotifications(int maxNotifications) {
+ mView.setMaxDisplayedNotifications(maxNotifications);
+ }
+
+ @Override
+ public ViewGroup getViewParentForNotification(NotificationEntry entry) {
+ return mView.getViewParentForNotification(entry);
+ }
+
+ @Override
+ public void resetExposedMenuView(boolean animate, boolean force) {
+ mView.resetExposedMenuView(animate, force);
+ }
+
+ @Override
+ public NotificationSwipeActionHelper getSwipeActionHelper() {
+ return mView.getSwipeActionHelper();
+ }
+
+ @Override
+ public void cleanUpViewStateForEntry(NotificationEntry entry) {
+ mView.cleanUpViewStateForEntry(entry);
+ }
+
+ @Override
+ public void setChildLocationsChangedListener(
+ NotificationLogger.OnChildLocationsChangedListener listener) {
+ mView.setChildLocationsChangedListener(listener);
+ }
+
+ public boolean hasPulsingNotifications() {
+ return mView.hasPulsingNotifications();
+ }
+
+ @Override
+ public boolean isInVisibleLocation(NotificationEntry entry) {
+ return mView.isInVisibleLocation(entry);
+ }
+
+ @Override
+ public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
+ mView.onChildHeightChanged(view, needsAnimation);
+ }
+
+ @Override
+ public void onReset(ExpandableView view) {
+ mView.onChildHeightReset(view);
+ }
+
+ @Override
+ public void bindRow(ExpandableNotificationRow row) {
+ mView.bindRow(row);
+ }
+
+ @Override
+ public void applyExpandAnimationParams(
+ ActivityLaunchAnimator.ExpandAnimationParameters params) {
+ mView.applyExpandAnimationParams(params);
+ }
+
+ @Override
+ public void setExpandingNotification(ExpandableNotificationRow row) {
+ mView.setExpandingNotification(row);
+ }
+
+ @Override
+ public boolean containsView(View v) {
+ return mView.containsView(v);
+ }
+
+ @Override
+ public void setWillExpand(boolean willExpand) {
+ mView.setWillExpand(willExpand);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppButtonData.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppButtonData.java
deleted file mode 100644
index f6c1062f6749..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppButtonData.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import android.app.ActivityManager.RecentTaskInfo;
-
-import java.util.ArrayList;
-
-/**
- * Data associated with an app button.
- */
-class AppButtonData {
- public final AppInfo appInfo;
- public boolean pinned;
- // Recent tasks for this app, sorted by lastActiveTime, descending.
- public ArrayList<RecentTaskInfo> tasks;
-
- public AppButtonData(AppInfo appInfo, boolean pinned) {
- this.appInfo = appInfo;
- this.pinned = pinned;
- }
-
- public int getTaskCount() {
- return tasks == null ? 0 : tasks.size();
- }
-
- /**
- * Returns true if the button contains no useful information and should be removed.
- */
- public boolean isEmpty() {
- return !pinned && getTaskCount() == 0;
- }
-
- public void addTask(RecentTaskInfo task) {
- if (tasks == null) {
- tasks = new ArrayList<RecentTaskInfo>();
- }
- tasks.add(task);
- }
-
- public void clearTasks() {
- if (tasks != null) {
- tasks.clear();
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java
deleted file mode 100644
index 8f0b532eabee..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AppInfo.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import android.content.ComponentName;
-import android.os.UserHandle;
-
-/**
- * Navigation bar app information.
- */
-class AppInfo {
- private final ComponentName mComponentName;
- private final UserHandle mUser;
-
- public AppInfo(ComponentName componentName, UserHandle user) {
- if (componentName == null || user == null) throw new IllegalArgumentException();
- mComponentName = componentName;
- mUser = user;
- }
-
- public ComponentName getComponentName() {
- return mComponentName;
- }
-
- public UserHandle getUser() {
- return mUser;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final AppInfo other = (AppInfo) obj;
- return mComponentName.equals(other.mComponentName) && mUser.equals(other.mUser);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
index d6039af9232a..aeb2efd2026a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
@@ -138,7 +138,7 @@ public class AutoHideController {
mHandler.postDelayed(mAutoHide, AUTO_HIDE_TIMEOUT_MS);
}
- void checkUserAutoHide(MotionEvent event) {
+ public void checkUserAutoHide(MotionEvent event) {
boolean shouldHide = isAnyTransientBarShown()
&& event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar.
&& event.getX() == 0 && event.getY() == 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index 0731a568ae7d..31965d4fc4cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -27,8 +27,8 @@ import android.view.ViewGroup;
import android.widget.LinearLayout;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.DemoMode;
import com.android.systemui.R;
+import com.android.systemui.demomode.DemoMode;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.StatusBarIconView;
@@ -39,7 +39,9 @@ import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconStat
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
import java.util.ArrayList;
+import java.util.List;
+//TODO: This should be a controller, not its own view
public class DemoStatusIcons extends StatusIconContainer implements DemoMode, DarkReceiver {
private static final String TAG = "DemoStatusIcons";
@@ -90,73 +92,84 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da
}
@Override
+ public List<String> demoCommands() {
+ List<String> commands = new ArrayList<>();
+ commands.add(COMMAND_STATUS);
+ return commands;
+ }
+
+ @Override
+ public void onDemoModeStarted() {
+ mDemoMode = true;
+ mStatusIcons.setVisibility(View.GONE);
+ setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onDemoModeFinished() {
+ mDemoMode = false;
+ mStatusIcons.setVisibility(View.VISIBLE);
+ setVisibility(View.GONE);
+ }
+
+ @Override
public void dispatchDemoCommand(String command, Bundle args) {
- if (!mDemoMode && command.equals(COMMAND_ENTER)) {
- mDemoMode = true;
- mStatusIcons.setVisibility(View.GONE);
- setVisibility(View.VISIBLE);
- } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
- mDemoMode = false;
- mStatusIcons.setVisibility(View.VISIBLE);
- setVisibility(View.GONE);
- } else if (mDemoMode && command.equals(COMMAND_STATUS)) {
- String volume = args.getString("volume");
- if (volume != null) {
- int iconId = volume.equals("vibrate") ? R.drawable.stat_sys_ringer_vibrate
- : 0;
- updateSlot("volume", null, iconId);
- }
- String zen = args.getString("zen");
- if (zen != null) {
- int iconId = zen.equals("dnd") ? R.drawable.stat_sys_dnd : 0;
- updateSlot("zen", null, iconId);
- }
- String bt = args.getString("bluetooth");
- if (bt != null) {
- int iconId = bt.equals("connected")
- ? R.drawable.stat_sys_data_bluetooth_connected : 0;
- updateSlot("bluetooth", null, iconId);
- }
- String location = args.getString("location");
- if (location != null) {
- int iconId = location.equals("show") ? PhoneStatusBarPolicy.LOCATION_STATUS_ICON_ID
- : 0;
- updateSlot("location", null, iconId);
- }
- String alarm = args.getString("alarm");
- if (alarm != null) {
- int iconId = alarm.equals("show") ? R.drawable.stat_sys_alarm
- : 0;
- updateSlot("alarm_clock", null, iconId);
- }
- String tty = args.getString("tty");
- if (tty != null) {
- int iconId = tty.equals("show") ? R.drawable.stat_sys_tty_mode
- : 0;
- updateSlot("tty", null, iconId);
- }
- String mute = args.getString("mute");
- if (mute != null) {
- int iconId = mute.equals("show") ? android.R.drawable.stat_notify_call_mute
- : 0;
- updateSlot("mute", null, iconId);
- }
- String speakerphone = args.getString("speakerphone");
- if (speakerphone != null) {
- int iconId = speakerphone.equals("show") ? android.R.drawable.stat_sys_speakerphone
- : 0;
- updateSlot("speakerphone", null, iconId);
- }
- String cast = args.getString("cast");
- if (cast != null) {
- int iconId = cast.equals("show") ? R.drawable.stat_sys_cast : 0;
- updateSlot("cast", null, iconId);
- }
- String hotspot = args.getString("hotspot");
- if (hotspot != null) {
- int iconId = hotspot.equals("show") ? R.drawable.stat_sys_hotspot : 0;
- updateSlot("hotspot", null, iconId);
- }
+ String volume = args.getString("volume");
+ if (volume != null) {
+ int iconId = volume.equals("vibrate") ? R.drawable.stat_sys_ringer_vibrate
+ : 0;
+ updateSlot("volume", null, iconId);
+ }
+ String zen = args.getString("zen");
+ if (zen != null) {
+ int iconId = zen.equals("dnd") ? R.drawable.stat_sys_dnd : 0;
+ updateSlot("zen", null, iconId);
+ }
+ String bt = args.getString("bluetooth");
+ if (bt != null) {
+ int iconId = bt.equals("connected")
+ ? R.drawable.stat_sys_data_bluetooth_connected : 0;
+ updateSlot("bluetooth", null, iconId);
+ }
+ String location = args.getString("location");
+ if (location != null) {
+ int iconId = location.equals("show") ? PhoneStatusBarPolicy.LOCATION_STATUS_ICON_ID
+ : 0;
+ updateSlot("location", null, iconId);
+ }
+ String alarm = args.getString("alarm");
+ if (alarm != null) {
+ int iconId = alarm.equals("show") ? R.drawable.stat_sys_alarm
+ : 0;
+ updateSlot("alarm_clock", null, iconId);
+ }
+ String tty = args.getString("tty");
+ if (tty != null) {
+ int iconId = tty.equals("show") ? R.drawable.stat_sys_tty_mode
+ : 0;
+ updateSlot("tty", null, iconId);
+ }
+ String mute = args.getString("mute");
+ if (mute != null) {
+ int iconId = mute.equals("show") ? android.R.drawable.stat_notify_call_mute
+ : 0;
+ updateSlot("mute", null, iconId);
+ }
+ String speakerphone = args.getString("speakerphone");
+ if (speakerphone != null) {
+ int iconId = speakerphone.equals("show") ? android.R.drawable.stat_sys_speakerphone
+ : 0;
+ updateSlot("speakerphone", null, iconId);
+ }
+ String cast = args.getString("cast");
+ if (cast != null) {
+ int iconId = cast.equals("show") ? R.drawable.stat_sys_cast : 0;
+ updateSlot("cast", null, iconId);
+ }
+ String hotspot = args.getString("hotspot");
+ if (hotspot != null) {
+ int iconId = hotspot.equals("show") ? R.drawable.stat_sys_hotspot : 0;
+ updateSlot("hotspot", null, iconId);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 3e5eb5fba8f2..982773aa9d86 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -32,6 +32,7 @@ import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.view.AppearanceRegion;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -125,7 +126,7 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
updateStatus();
}
- void onNavigationBarAppearanceChanged(@Appearance int appearance, boolean nbModeChanged,
+ public void onNavigationBarAppearanceChanged(@Appearance int appearance, boolean nbModeChanged,
int navigationBarMode, boolean navbarColorManagedByIme) {
int diff = appearance ^ mAppearance;
if ((diff & APPEARANCE_LIGHT_NAVIGATION_BARS) != 0 || nbModeChanged) {
@@ -144,7 +145,7 @@ public class LightBarController implements BatteryController.BatteryStateChangeC
mNavbarColorManagedByIme = navbarColorManagedByIme;
}
- void onNavigationBarModeChanged(int newBarMode) {
+ public void onNavigationBarModeChanged(int newBarMode) {
mHasLightNavigationBar = isLight(mAppearance, newBarMode, APPEARANCE_LIGHT_NAVIGATION_BARS);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java
index 07e9f944b802..8e9dcb4375d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImpl.java
@@ -24,6 +24,8 @@ import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
+import androidx.annotation.NonNull;
+
import com.android.systemui.broadcast.BroadcastDispatcher;
import java.util.ArrayList;
@@ -57,7 +59,8 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
mProfiles = new LinkedList<UserInfo>();
}
- public void addCallback(Callback callback) {
+ @Override
+ public void addCallback(@NonNull Callback callback) {
mCallbacks.add(callback);
if (mCallbacks.size() == 1) {
setListening(true);
@@ -65,7 +68,8 @@ public class ManagedProfileControllerImpl implements ManagedProfileController {
callback.onManagedProfileChanged();
}
- public void removeCallback(Callback callback) {
+ @Override
+ public void removeCallback(@NonNull Callback callback) {
if (mCallbacks.remove(callback) && mCallbacks.size() == 0) {
setListening(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 7bbe1c986249..0e413fba0ad5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -5,6 +5,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
+import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -20,6 +21,8 @@ import com.android.settingslib.Utils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.demomode.DemoMode;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -35,6 +38,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import java.util.function.Function;
@@ -44,7 +48,8 @@ import java.util.function.Function;
*/
public class NotificationIconAreaController implements DarkReceiver,
StatusBarStateController.StateListener,
- NotificationWakeUpCoordinator.WakeUpListener {
+ NotificationWakeUpCoordinator.WakeUpListener,
+ DemoMode {
public static final String HIGH_PRIORITY = "high_priority";
private static final long AOD_ICONS_APPEAR_DURATION = 200;
@@ -74,6 +79,8 @@ public class NotificationIconAreaController implements DarkReceiver,
private final Rect mTintArea = new Rect();
private ViewGroup mNotificationScrollLayout;
private Context mContext;
+ private final DemoModeController mDemoModeController;
+
private int mAodIconAppearTranslation;
private boolean mAnimationsEnabled;
@@ -104,7 +111,8 @@ public class NotificationIconAreaController implements DarkReceiver,
NotificationMediaManager notificationMediaManager,
NotificationListener notificationListener,
DozeParameters dozeParameters,
- BubbleController bubbleController) {
+ BubbleController bubbleController,
+ DemoModeController demoModeController) {
mStatusBar = statusBar;
mContrastColorUtil = ContrastColorUtil.getInstance(context);
mContext = context;
@@ -117,6 +125,8 @@ public class NotificationIconAreaController implements DarkReceiver,
mBypassController = keyguardBypassController;
mBubbleController = bubbleController;
notificationListener.addNotificationSettingsListener(mSettingsListener);
+ mDemoModeController = demoModeController;
+ mDemoModeController.addCallback(this);
initializeNotificationAreaViews(context);
reloadAodColor();
@@ -666,4 +676,27 @@ public class NotificationIconAreaController implements DarkReceiver,
}
}
}
+
+ @Override
+ public List<String> demoCommands() {
+ ArrayList<String> commands = new ArrayList<>();
+ commands.add(DemoMode.COMMAND_NOTIFICATIONS);
+ return commands;
+ }
+
+ @Override
+ public void dispatchDemoCommand(String command, Bundle args) {
+ if (mNotificationIconArea != null) {
+ String visible = args.getString("visible");
+ int vis = "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
+ mNotificationIconArea.setVisibility(vis);
+ }
+ }
+
+ @Override
+ public void onDemoModeFinished() {
+ if (mNotificationIconArea != null) {
+ mNotificationIconArea.setVisibility(View.VISIBLE);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 70fb71a1d2f2..42fbe5967d42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -3074,7 +3074,8 @@ public class NotificationPanelViewController extends PanelViewController {
}
public boolean hasPulsingNotifications() {
- return mNotificationStackScrollLayoutController.hasPulsingNotifications();
+ return mNotificationStackScrollLayoutController
+ .getNotificationListContainer().hasPulsingNotifications();
}
public ActivatableNotificationView getActivatedChild() {
@@ -3259,6 +3260,10 @@ public class NotificationPanelViewController extends PanelViewController {
return new OnConfigurationChangedListener();
}
+ public NotificationStackScrollLayoutController getNotificationStackScrollLayoutController() {
+ return mNotificationStackScrollLayoutController;
+ }
+
private class OnHeightChangedListener implements ExpandableView.OnHeightChangedListener {
@Override
public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 6cd33c6872c7..4fbd49a6fe4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -138,7 +138,6 @@ import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.AutoReinflateContainer;
import com.android.systemui.DejankUtils;
-import com.android.systemui.DemoMode;
import com.android.systemui.Dumpable;
import com.android.systemui.EventLogTags;
import com.android.systemui.InitController;
@@ -153,12 +152,17 @@ import com.android.systemui.charging.WirelessChargingAnimation;
import com.android.systemui.classifier.FalsingLog;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.demomode.DemoMode;
+import com.android.systemui.demomode.DemoModeCommandReceiver;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.fragments.ExtensionFragmentListener;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.FalsingManager;
@@ -182,7 +186,6 @@ import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.GestureRecorder;
import com.android.systemui.statusbar.KeyboardShortcuts;
import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.NavigationBarController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationPresenter;
@@ -210,6 +213,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -231,6 +235,8 @@ import com.android.systemui.volume.VolumeComponent;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Executor;
@@ -395,6 +401,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private final ExtensionController mExtensionController;
private final UserInfoControllerImpl mUserInfoControllerImpl;
private final DismissCallbackRegistry mDismissCallbackRegistry;
+ private final DemoModeController mDemoModeController;
private NotificationsController mNotificationsController;
// expanded notifications
@@ -646,6 +653,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private final BubbleController.BubbleExpandListener mBubbleExpandListener;
private ActivityIntentHelper mActivityIntentHelper;
+ private NotificationStackScrollLayoutController mStackScrollerController;
/**
* Public constructor for StatusBar.
@@ -731,6 +739,7 @@ public class StatusBar extends SystemUI implements DemoMode,
PhoneStatusBarPolicy phoneStatusBarPolicy,
KeyguardIndicationController keyguardIndicationController,
DismissCallbackRegistry dismissCallbackRegistry,
+ DemoModeController demoModeController,
Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
super(context);
@@ -809,6 +818,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mUserInfoControllerImpl = userInfoControllerImpl;
mIconPolicy = phoneStatusBarPolicy;
mDismissCallbackRegistry = dismissCallbackRegistry;
+ mDemoModeController = demoModeController;
mBubbleExpandListener =
(isExpanding, key) -> {
@@ -863,6 +873,9 @@ public class StatusBar extends SystemUI implements DemoMode,
// Connect in to the status bar manager service
mCommandQueue.addCallback(this);
+ // Listen for demo mode changes
+ mDemoModeController.addCallback(this);
+
RegisterStatusBarResult result = null;
try {
result = mBarService.registerStatusBar(mCommandQueue);
@@ -1016,9 +1029,11 @@ public class StatusBar extends SystemUI implements DemoMode,
// TODO: Deal with the ugliness that comes from having some of the statusbar broken out
// into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
- mStackScroller = mNotificationShadeWindowView.findViewById(
- R.id.notification_stack_scroller);
- NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
+ mStackScrollerController =
+ mNotificationPanelViewController.getNotificationStackScrollLayoutController();
+ mStackScroller = mStackScrollerController.getView();
+ NotificationListContainer notifListContainer =
+ mStackScrollerController.getNotificationListContainer();
mNotificationLogger.setUpWithContainer(notifListContainer);
// TODO: make this injectable. Currently that would create a circular dependency between
@@ -1026,7 +1041,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationIconAreaController = SystemUIFactory.getInstance()
.createNotificationIconAreaController(context, this,
mWakeUpCoordinator, mKeyguardBypassController,
- mStatusBarStateController);
+ mStatusBarStateController, mDemoModeController);
mWakeUpCoordinator.setIconAreaController(mNotificationIconAreaController);
inflateShelf();
mNotificationIconAreaController.setupShelf(mNotificationShelfController);
@@ -1249,7 +1264,6 @@ public class StatusBar extends SystemUI implements DemoMode,
if (DEBUG_MEDIA_FAKE_ARTWORK) {
demoFilter.addAction(ACTION_FAKE_ARTWORK);
}
- demoFilter.addAction(ACTION_DEMO);
context.registerReceiverAsUser(mDemoReceiver, UserHandle.ALL, demoFilter,
android.Manifest.permission.DUMP, null);
@@ -1301,13 +1315,15 @@ public class StatusBar extends SystemUI implements DemoMode,
mActivityLaunchAnimator = new ActivityLaunchAnimator(
mNotificationShadeWindowViewController, this, mNotificationPanelViewController,
mNotificationShadeDepthControllerLazy.get(),
- (NotificationListContainer) mStackScroller, mContext.getMainExecutor());
+ mStackScrollerController.getNotificationListContainer(),
+ mContext.getMainExecutor());
// TODO: inject this.
mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanelViewController,
- mHeadsUpManager, mNotificationShadeWindowView, mStackScroller, mDozeScrimController,
- mScrimController, mActivityLaunchAnimator, mDynamicPrivacyController,
- mKeyguardStateController, mKeyguardIndicationController,
+ mHeadsUpManager, mNotificationShadeWindowView, mStackScrollerController,
+ mDozeScrimController, mScrimController, mActivityLaunchAnimator,
+ mDynamicPrivacyController, mKeyguardStateController,
+ mKeyguardIndicationController,
this /* statusBar */, mShadeController, mCommandQueue, mInitController,
mNotificationInterruptStateProvider);
@@ -1321,16 +1337,13 @@ public class StatusBar extends SystemUI implements DemoMode,
.setNotificationPresenter(mPresenter)
.setNotificationPanelViewController(mNotificationPanelViewController)
.build();
-
- ((NotificationListContainer) mStackScroller)
- .setNotificationActivityStarter(mNotificationActivityStarter);
-
+ mStackScroller.setNotificationActivityStarter(mNotificationActivityStarter);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
mNotificationsController.initialize(
this,
mPresenter,
- (NotificationListContainer) mStackScroller,
+ mStackScrollerController.getNotificationListContainer(),
mNotificationActivityStarter,
mPresenter);
}
@@ -1502,7 +1515,7 @@ public class StatusBar extends SystemUI implements DemoMode,
return mStatusBarWindowController.getStatusBarHeight();
}
- protected boolean toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
+ public boolean toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
if (!mRecentsOptional.isPresent()) {
return false;
}
@@ -2435,8 +2448,8 @@ public class StatusBar extends SystemUI implements DemoMode,
return mNotificationShadeWindowViewController.getBarTransitions();
}
- void checkBarModes() {
- if (mDemoMode) return;
+ public void checkBarModes() {
+ if (mDemoModeController.isInDemoMode()) return;
if (mNotificationShadeWindowViewController != null && getStatusBarTransitions() != null) {
checkBarMode(mStatusBarMode, mStatusBarWindowState, getStatusBarTransitions());
}
@@ -2445,7 +2458,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
// Called by NavigationBarFragment
- void setQsScrimEnabled(boolean scrimEnabled) {
+ public void setQsScrimEnabled(boolean scrimEnabled) {
mNotificationPanelViewController.setQsScrimEnabled(scrimEnabled);
}
@@ -2618,7 +2631,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
+ public static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
pw.println(BarTransitions.modeToString(transitions.getMode()));
}
@@ -2809,19 +2822,7 @@ public class StatusBar extends SystemUI implements DemoMode,
public void onReceive(Context context, Intent intent) {
if (DEBUG) Log.v(TAG, "onReceive: " + intent);
String action = intent.getAction();
- if (ACTION_DEMO.equals(action)) {
- Bundle bundle = intent.getExtras();
- if (bundle != null) {
- String command = bundle.getString("command", "").trim().toLowerCase();
- if (command.length() > 0) {
- try {
- dispatchDemoCommand(command, bundle);
- } catch (Throwable t) {
- Log.w(TAG, "Error running demo command, intent=" + intent, t);
- }
- }
- }
- } else if (ACTION_FAKE_ARTWORK.equals(action)) {
+ if (ACTION_FAKE_ARTWORK.equals(action)) {
if (DEBUG_MEDIA_FAKE_ARTWORK) {
mPresenter.updateMediaMetaData(true, true);
}
@@ -3085,50 +3086,34 @@ public class StatusBar extends SystemUI implements DemoMode,
startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
}
- private boolean mDemoModeAllowed;
- private boolean mDemoMode;
+ @Override
+ public List<String> demoCommands() {
+ List<String> s = new ArrayList<>();
+ s.add(DemoMode.COMMAND_BARS);
+ s.add(DemoMode.COMMAND_CLOCK);
+ s.add(DemoMode.COMMAND_OPERATOR);
+ return s;
+ }
@Override
- public void dispatchDemoCommand(String command, Bundle args) {
- if (!mDemoModeAllowed) {
- mDemoModeAllowed = Settings.Global.getInt(mContext.getContentResolver(),
- DEMO_MODE_ALLOWED, 0) != 0;
- }
- if (!mDemoModeAllowed) return;
- if (command.equals(COMMAND_ENTER)) {
- mDemoMode = true;
- } else if (command.equals(COMMAND_EXIT)) {
- mDemoMode = false;
- checkBarModes();
- } else if (!mDemoMode) {
- // automatically enter demo mode on first demo command
- dispatchDemoCommand(COMMAND_ENTER, new Bundle());
- }
- boolean modeChange = command.equals(COMMAND_ENTER) || command.equals(COMMAND_EXIT);
- if ((modeChange || command.equals(COMMAND_VOLUME)) && mVolumeComponent != null) {
- mVolumeComponent.dispatchDemoCommand(command, args);
- }
- if (modeChange || command.equals(COMMAND_CLOCK)) {
+ public void onDemoModeStarted() {
+ // Must send this message to any view that we delegate to via dispatchDemoCommandToView
+ dispatchDemoModeStartedToView(R.id.clock);
+ dispatchDemoModeStartedToView(R.id.operator_name);
+ }
+
+ @Override
+ public void onDemoModeFinished() {
+ dispatchDemoModeFinishedToView(R.id.clock);
+ dispatchDemoModeFinishedToView(R.id.operator_name);
+ checkBarModes();
+ }
+
+ @Override
+ public void dispatchDemoCommand(String command, @NonNull Bundle args) {
+ if (command.equals(COMMAND_CLOCK)) {
dispatchDemoCommandToView(command, args, R.id.clock);
}
- if (modeChange || command.equals(COMMAND_BATTERY)) {
- mBatteryController.dispatchDemoCommand(command, args);
- }
- if (modeChange || command.equals(COMMAND_STATUS)) {
- ((StatusBarIconControllerImpl) mIconController).dispatchDemoCommand(command, args);
- }
- if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
- mNetworkController.dispatchDemoCommand(command, args);
- }
- if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
- View notifications = mStatusBarView == null ? null
- : mStatusBarView.findViewById(R.id.notification_icon_area);
- if (notifications != null) {
- String visible = args.getString("visible");
- int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
- notifications.setVisibility(vis);
- }
- }
if (command.equals(COMMAND_BARS)) {
String mode = args.getString("mode");
int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
@@ -3147,16 +3132,33 @@ public class StatusBar extends SystemUI implements DemoMode,
mNavigationBarController.transitionTo(mDisplayId, barMode, animate);
}
}
- if (modeChange || command.equals(COMMAND_OPERATOR)) {
+ if (command.equals(COMMAND_OPERATOR)) {
dispatchDemoCommandToView(command, args, R.id.operator_name);
}
}
+ //TODO: these should have controllers, and this method should be removed
private void dispatchDemoCommandToView(String command, Bundle args, int id) {
if (mStatusBarView == null) return;
View v = mStatusBarView.findViewById(id);
- if (v instanceof DemoMode) {
- ((DemoMode)v).dispatchDemoCommand(command, args);
+ if (v instanceof DemoModeCommandReceiver) {
+ ((DemoModeCommandReceiver) v).dispatchDemoCommand(command, args);
+ }
+ }
+
+ private void dispatchDemoModeStartedToView(int id) {
+ if (mStatusBarView == null) return;
+ View v = mStatusBarView.findViewById(id);
+ if (v instanceof DemoModeCommandReceiver) {
+ ((DemoModeCommandReceiver) v).onDemoModeStarted();
+ }
+ }
+
+ private void dispatchDemoModeFinishedToView(int id) {
+ if (mStatusBarView == null) return;
+ View v = mStatusBarView.findViewById(id);
+ if (v instanceof DemoModeCommandReceiver) {
+ ((DemoModeCommandReceiver) v).onDemoModeFinished();
}
}
@@ -4132,7 +4134,7 @@ public class StatusBar extends SystemUI implements DemoMode,
toggleSplitScreenMode(-1 /* metricsDockAction */, -1 /* metricsUndockAction */);
}
- void awakenDreams() {
+ public void awakenDreams() {
mUiBgExecutor.execute(() -> {
try {
mDreamManager.awaken();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 8ff7a41cb22f..f0efed332c7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -32,9 +32,9 @@ import android.widget.LinearLayout.LayoutParams;
import androidx.annotation.VisibleForTesting;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.DemoMode;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.demomode.DemoModeCommandReceiver;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.CommandQueue;
@@ -198,7 +198,7 @@ public interface StatusBarIconController {
/**
* Turns info from StatusBarIconController into ImageViews in a ViewGroup.
*/
- public static class IconManager implements DemoMode {
+ class IconManager implements DemoModeCommandReceiver {
protected final ViewGroup mGroup;
protected final Context mContext;
protected final int mIconSize;
@@ -390,18 +390,24 @@ public interface StatusBarIconController {
return;
}
- if (command.equals(COMMAND_EXIT)) {
- if (mDemoStatusIcons != null) {
- mDemoStatusIcons.dispatchDemoCommand(command, args);
- exitDemoMode();
- }
+ mDemoStatusIcons.dispatchDemoCommand(command, args);
+ }
+
+ @Override
+ public void onDemoModeStarted() {
+ mIsInDemoMode = true;
+ if (mDemoStatusIcons == null) {
+ mDemoStatusIcons = createDemoStatusIcons();
+ }
+ mDemoStatusIcons.onDemoModeStarted();
+ }
+
+ @Override
+ public void onDemoModeFinished() {
+ if (mDemoStatusIcons != null) {
+ mDemoStatusIcons.onDemoModeFinished();
+ exitDemoMode();
mIsInDemoMode = false;
- } else {
- if (mDemoStatusIcons == null) {
- mIsInDemoMode = true;
- mDemoStatusIcons = createDemoStatusIcons();
- }
- mDemoStatusIcons.dispatchDemoCommand(command, args);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 21e1d319cffa..60ef52351393 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -29,6 +29,8 @@ import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
+import com.android.systemui.demomode.DemoMode;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
@@ -54,22 +56,20 @@ import javax.inject.Singleton;
*/
@Singleton
public class StatusBarIconControllerImpl extends StatusBarIconList implements Tunable,
- ConfigurationListener, Dumpable, CommandQueue.Callbacks, StatusBarIconController {
+ ConfigurationListener, Dumpable, CommandQueue.Callbacks, StatusBarIconController, DemoMode {
private static final String TAG = "StatusBarIconController";
private final ArrayList<IconManager> mIconGroups = new ArrayList<>();
private final ArraySet<String> mIconHideList = new ArraySet<>();
- // Points to light or dark context depending on the... context?
private Context mContext;
- private Context mLightContext;
- private Context mDarkContext;
-
- private boolean mIsDark = false;
@Inject
- public StatusBarIconControllerImpl(Context context, CommandQueue commandQueue) {
+ public StatusBarIconControllerImpl(
+ Context context,
+ CommandQueue commandQueue,
+ DemoModeController demoModeController) {
super(context.getResources().getStringArray(
com.android.internal.R.array.config_statusBarIcons));
Dependency.get(ConfigurationController.class).addCallback(this);
@@ -80,6 +80,7 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
commandQueue.addCallback(this);
Dependency.get(TunerService.class).addTunable(this, ICON_HIDE_LIST);
+ demoModeController.addCallback(this);
}
@Override
@@ -339,6 +340,25 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
super.dump(pw);
}
+ @Override
+ public void onDemoModeStarted() {
+ for (IconManager manager : mIconGroups) {
+ if (manager.isDemoable()) {
+ manager.onDemoModeStarted();
+ }
+ }
+ }
+
+ @Override
+ public void onDemoModeFinished() {
+ for (IconManager manager : mIconGroups) {
+ if (manager.isDemoable()) {
+ manager.onDemoModeFinished();
+ }
+ }
+ }
+
+ @Override
public void dispatchDemoCommand(String command, Bundle args) {
for (IconManager manager : mIconGroups) {
if (manager.isDemoable()) {
@@ -348,6 +368,13 @@ public class StatusBarIconControllerImpl extends StatusBarIconList implements Tu
}
@Override
+ public List<String> demoCommands() {
+ List<String> s = new ArrayList<>();
+ s.add(DemoMode.COMMAND_STATUS);
+ return s;
+ }
+
+ @Override
public void onDensityOrFontScaleChanged() {
loadDimens();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 81d0699a29e6..f3a7c501f6e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -49,6 +49,7 @@ import com.android.systemui.DejankUtils;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.system.QuickStepContract;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 4de648402464..b9f94b37d7d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -49,7 +49,6 @@ import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.EventLogTags;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.bubbles.BubbleController;
-import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.plugins.ActivityStarter;
@@ -93,7 +92,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final CommandQueue mCommandQueue;
private final Handler mMainThreadHandler;
- private final Handler mBackgroundHandler;
private final Executor mUiBgExecutor;
private final NotificationEntryManager mEntryManager;
@@ -134,7 +132,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
Context context,
CommandQueue commandQueue,
Handler mainThreadHandler,
- Handler backgroundHandler,
Executor uiBgExecutor,
NotificationEntryManager entryManager,
NotifPipeline notifPipeline,
@@ -170,7 +167,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mContext = context;
mCommandQueue = commandQueue;
mMainThreadHandler = mainThreadHandler;
- mBackgroundHandler = backgroundHandler;
mUiBgExecutor = uiBgExecutor;
mEntryManager = entryManager;
mNotifPipeline = notifPipeline;
@@ -307,7 +303,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
mShadeController.collapsePanel();
} else {
- mBackgroundHandler.postAtFrontOfQueue(runnable);
+ runnable.run();
}
return !mNotificationPanel.isFullyCollapsed();
}
@@ -605,7 +601,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final Context mContext;
private final CommandQueue mCommandQueue;
private final Handler mMainThreadHandler;
- private final Handler mBackgroundHandler;
+
private final Executor mUiBgExecutor;
private final NotificationEntryManager mEntryManager;
private final NotifPipeline mNotifPipeline;
@@ -644,7 +640,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
Context context,
CommandQueue commandQueue,
@Main Handler mainThreadHandler,
- @Background Handler backgroundHandler,
@UiBackground Executor uiBgExecutor,
NotificationEntryManager entryManager,
NotifPipeline notifPipeline,
@@ -676,7 +671,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mContext = context;
mCommandQueue = commandQueue;
mMainThreadHandler = mainThreadHandler;
- mBackgroundHandler = backgroundHandler;
mUiBgExecutor = uiBgExecutor;
mEntryManager = entryManager;
mNotifPipeline = notifPipeline;
@@ -734,7 +728,6 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mContext,
mCommandQueue,
mMainThreadHandler,
- mBackgroundHandler,
mUiBgExecutor,
mEntryManager,
mNotifPipeline,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 45f0c49a4fd4..f1715bef62d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -30,7 +30,6 @@ import android.service.vr.IVrStateCallbacks;
import android.util.Log;
import android.util.Slog;
import android.view.View;
-import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
import android.widget.TextView;
@@ -71,7 +70,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -133,7 +132,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
NotificationPanelViewController panel,
HeadsUpManagerPhone headsUp,
NotificationShadeWindowView statusBarWindow,
- ViewGroup stackScroller,
+ NotificationStackScrollLayoutController stackScrollerController,
DozeScrimController dozeScrimController,
ScrimController scrimController,
ActivityLaunchAnimator activityLaunchAnimator,
@@ -155,7 +154,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
mStatusBar = statusBar;
mShadeController = shadeController;
mCommandQueue = commandQueue;
- mAboveShelfObserver = new AboveShelfObserver(stackScroller);
+ mAboveShelfObserver = new AboveShelfObserver(stackScrollerController.getView());
mActivityLaunchAnimator = activityLaunchAnimator;
mAboveShelfObserver.setListener(statusBarWindow.findViewById(
R.id.notification_container_parent));
@@ -190,7 +189,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
remoteInputManager.getController().addCallback(
Dependency.get(NotificationShadeWindowController.class));
- NotificationListContainer notifListContainer = (NotificationListContainer) stackScroller;
initController.addPostInitTask(() -> {
NotificationEntryListener notificationEntryListener = new NotificationEntryListener() {
@Override
@@ -207,7 +205,8 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
}
};
- mViewHierarchyManager.setUpWithPresenter(this, notifListContainer);
+ mViewHierarchyManager.setUpWithPresenter(this,
+ stackScrollerController.getNotificationListContainer());
mEntryManager.setUpWithPresenter(this);
mEntryManager.addNotificationEntryListener(notificationEntryListener);
mEntryManager.addNotificationLifetimeExtender(mHeadsUpManager);
@@ -219,7 +218,8 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
mMediaManager.setUpWithPresenter(this);
mVisualStabilityManager.setUpWithPresenter(this);
mGutsManager.setUpWithPresenter(this,
- notifListContainer, mCheckSaveListener, mOnSettingsClickListener);
+ stackScrollerController.getNotificationListContainer(), mCheckSaveListener,
+ mOnSettingsClickListener);
// ForegroundServiceNotificationListener adds its listener in its constructor
// but we need to request it here in order for it to be instantiated.
// TODO: figure out how to do this correctly once Dependency.get() is gone.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 02e031217904..dd4af540b2f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -34,10 +34,12 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.PluginDependencyProvider;
@@ -47,7 +49,6 @@ import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.NavigationBarController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -196,6 +197,7 @@ public interface StatusBarPhoneModule {
UserInfoControllerImpl userInfoControllerImpl,
PhoneStatusBarPolicy phoneStatusBarPolicy,
KeyguardIndicationController keyguardIndicationController,
+ DemoModeController demoModeController,
Lazy<NotificationShadeDepthController> notificationShadeDepthController,
DismissCallbackRegistry dismissCallbackRegistry,
StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
@@ -275,6 +277,7 @@ public interface StatusBarPhoneModule {
phoneStatusBarPolicy,
keyguardIndicationController,
dismissCallbackRegistry,
+ demoModeController,
notificationShadeDepthController,
statusBarTouchableRegionManager);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java
index 1395e1377529..c0caabd7501a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityManagerWrapper.java
@@ -19,6 +19,8 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
+import androidx.annotation.NonNull;
+
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -37,12 +39,12 @@ public class AccessibilityManagerWrapper implements
}
@Override
- public void addCallback(AccessibilityServicesStateChangeListener listener) {
+ public void addCallback(@NonNull AccessibilityServicesStateChangeListener listener) {
mAccessibilityManager.addAccessibilityServicesStateChangeListener(listener, null);
}
@Override
- public void removeCallback(AccessibilityServicesStateChangeListener listener) {
+ public void removeCallback(@NonNull AccessibilityServicesStateChangeListener listener) {
mAccessibilityManager.removeAccessibilityServicesStateChangeListener(listener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index e5a46797d035..06e4731265e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -18,8 +18,8 @@ package com.android.systemui.statusbar.policy;
import android.annotation.Nullable;
-import com.android.systemui.DemoMode;
import com.android.systemui.Dumpable;
+import com.android.systemui.demomode.DemoMode;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
import java.io.FileDescriptor;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 88a6263c1dca..b7dc821e4a8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -27,6 +27,7 @@ import android.os.PowerManager;
import android.os.PowerSaveState;
import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
@@ -36,11 +37,14 @@ import com.android.settingslib.utils.PowerUtil;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.demomode.DemoMode;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.power.EnhancedEstimates;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -63,6 +67,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
mChangeCallbacks = new ArrayList<>();
private final ArrayList<EstimateFetchCompletion> mFetchCallbacks = new ArrayList<>();
private final PowerManager mPowerManager;
+ private final DemoModeController mDemoModeController;
private final Handler mMainHandler;
private final Handler mBgHandler;
protected final Context mContext;
@@ -82,15 +87,21 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
@VisibleForTesting
@Inject
- public BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates,
- PowerManager powerManager, BroadcastDispatcher broadcastDispatcher,
- @Main Handler mainHandler, @Background Handler bgHandler) {
+ public BatteryControllerImpl(
+ Context context,
+ EnhancedEstimates enhancedEstimates,
+ PowerManager powerManager,
+ BroadcastDispatcher broadcastDispatcher,
+ DemoModeController demoModeController,
+ @Main Handler mainHandler,
+ @Background Handler bgHandler) {
mContext = context;
mMainHandler = mainHandler;
mBgHandler = bgHandler;
mPowerManager = powerManager;
mEstimates = enhancedEstimates;
mBroadcastDispatcher = broadcastDispatcher;
+ mDemoModeController = demoModeController;
}
private void registerReceiver() {
@@ -114,6 +125,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
onReceive(mContext, intent);
}
}
+ mDemoModeController.addCallback(this);
updatePowerSave();
updateEstimate();
}
@@ -134,7 +146,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
}
@Override
- public void addCallback(BatteryController.BatteryStateChangeCallback cb) {
+ public void addCallback(@NonNull BatteryController.BatteryStateChangeCallback cb) {
synchronized (mChangeCallbacks) {
mChangeCallbacks.add(cb);
}
@@ -144,7 +156,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
}
@Override
- public void removeCallback(BatteryController.BatteryStateChangeCallback cb) {
+ public void removeCallback(@NonNull BatteryController.BatteryStateChangeCallback cb) {
synchronized (mChangeCallbacks) {
mChangeCallbacks.remove(cb);
}
@@ -325,32 +337,43 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
}
}
- private boolean mDemoMode;
-
@Override
public void dispatchDemoCommand(String command, Bundle args) {
- if (!mDemoMode && command.equals(COMMAND_ENTER)) {
- mDemoMode = true;
- mBroadcastDispatcher.unregisterReceiver(this);
- } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
- mDemoMode = false;
- registerReceiver();
- updatePowerSave();
- } else if (mDemoMode && command.equals(COMMAND_BATTERY)) {
- String level = args.getString("level");
- String plugged = args.getString("plugged");
- String powerSave = args.getString("powersave");
- if (level != null) {
- mLevel = Math.min(Math.max(Integer.parseInt(level), 0), 100);
- }
- if (plugged != null) {
- mPluggedIn = Boolean.parseBoolean(plugged);
- }
- if (powerSave != null) {
- mPowerSave = powerSave.equals("true");
- firePowerSaveChanged();
- }
- fireBatteryLevelChanged();
+ if (!mDemoModeController.isInDemoMode()) {
+ return;
+ }
+
+ String level = args.getString("level");
+ String plugged = args.getString("plugged");
+ String powerSave = args.getString("powersave");
+ if (level != null) {
+ mLevel = Math.min(Math.max(Integer.parseInt(level), 0), 100);
+ }
+ if (plugged != null) {
+ mPluggedIn = Boolean.parseBoolean(plugged);
+ }
+ if (powerSave != null) {
+ mPowerSave = powerSave.equals("true");
+ firePowerSaveChanged();
}
+ fireBatteryLevelChanged();
+ }
+
+ @Override
+ public List<String> demoCommands() {
+ List<String> s = new ArrayList<>();
+ s.add(DemoMode.COMMAND_BATTERY);
+ return s;
+ }
+
+ @Override
+ public void onDemoModeStarted() {
+ mBroadcastDispatcher.unregisterReceiver(this);
+ }
+
+ @Override
+ public void onDemoModeFinished() {
+ registerReceiver();
+ updatePowerSave();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 0fc3d8481907..8110ab44f09d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -29,6 +29,8 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -150,13 +152,13 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
}
@Override
- public void addCallback(Callback cb) {
+ public void addCallback(@NonNull Callback cb) {
mHandler.obtainMessage(H.MSG_ADD_CALLBACK, cb).sendToTarget();
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
@Override
- public void removeCallback(Callback cb) {
+ public void removeCallback(@NonNull Callback cb) {
mHandler.obtainMessage(H.MSG_REMOVE_CALLBACK, cb).sendToTarget();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 78111fb61fd0..a0b03e1c54c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -123,13 +123,13 @@ public class BrightnessMirrorController
}
@Override
- public void addCallback(BrightnessMirrorListener listener) {
+ public void addCallback(@NonNull BrightnessMirrorListener listener) {
Objects.requireNonNull(listener);
mBrightnessMirrorListeners.add(listener);
}
@Override
- public void removeCallback(BrightnessMirrorListener listener) {
+ public void removeCallback(@NonNull BrightnessMirrorListener listener) {
mBrightnessMirrorListeners.remove(listener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackController.java
index 626eef5867f2..047ff75468ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackController.java
@@ -15,14 +15,19 @@
package com.android.systemui.statusbar.policy;
+import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.Lifecycle.Event;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;
public interface CallbackController<T> {
- void addCallback(T listener);
- void removeCallback(T listener);
+
+ /** Add a callback */
+ void addCallback(@NonNull T listener);
+
+ /** Remove a callback */
+ void removeCallback(@NonNull T listener);
/**
* Wrapper to {@link #addCallback(Object)} when a lifecycle is in the resumed state
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index 6106f38c0e60..f38c73100292 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -31,6 +31,7 @@ import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.android.internal.annotations.GuardedBy;
@@ -95,7 +96,7 @@ public class CastControllerImpl implements CastController {
}
@Override
- public void addCallback(Callback callback) {
+ public void addCallback(@NonNull Callback callback) {
synchronized (mCallbacks) {
mCallbacks.add(callback);
}
@@ -106,7 +107,7 @@ public class CastControllerImpl implements CastController {
}
@Override
- public void removeCallback(Callback callback) {
+ public void removeCallback(@NonNull Callback callback) {
synchronized (mCallbacks) {
mCallbacks.remove(callback);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 120a0e3abba4..ef35a3c55ab8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -40,11 +40,11 @@ import android.view.View;
import android.widget.TextView;
import com.android.settingslib.Utils;
-import com.android.systemui.DemoMode;
import com.android.systemui.Dependency;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.demomode.DemoModeCommandReceiver;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.settings.CurrentUserTracker;
@@ -62,7 +62,10 @@ import java.util.TimeZone;
/**
* Digital clock for the status bar.
*/
-public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.Callbacks,
+public class Clock extends TextView implements
+ DemoModeCommandReceiver,
+ Tunable,
+ CommandQueue.Callbacks,
DarkReceiver, ConfigurationListener {
public static final String CLOCK_SECONDS = "clock_seconds";
@@ -467,30 +470,35 @@ public class Clock extends TextView implements DemoMode, Tunable, CommandQueue.C
@Override
public void dispatchDemoCommand(String command, Bundle args) {
- if (!mDemoMode && command.equals(COMMAND_ENTER)) {
- mDemoMode = true;
- } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
- mDemoMode = false;
- updateClock();
- } else if (mDemoMode && command.equals(COMMAND_CLOCK)) {
- String millis = args.getString("millis");
- String hhmm = args.getString("hhmm");
- if (millis != null) {
- mCalendar.setTimeInMillis(Long.parseLong(millis));
- } else if (hhmm != null && hhmm.length() == 4) {
- int hh = Integer.parseInt(hhmm.substring(0, 2));
- int mm = Integer.parseInt(hhmm.substring(2));
- boolean is24 = DateFormat.is24HourFormat(getContext(), mCurrentUserId);
- if (is24) {
- mCalendar.set(Calendar.HOUR_OF_DAY, hh);
- } else {
- mCalendar.set(Calendar.HOUR, hh);
- }
- mCalendar.set(Calendar.MINUTE, mm);
+ // Only registered for COMMAND_CLOCK
+ String millis = args.getString("millis");
+ String hhmm = args.getString("hhmm");
+ if (millis != null) {
+ mCalendar.setTimeInMillis(Long.parseLong(millis));
+ } else if (hhmm != null && hhmm.length() == 4) {
+ int hh = Integer.parseInt(hhmm.substring(0, 2));
+ int mm = Integer.parseInt(hhmm.substring(2));
+ boolean is24 = DateFormat.is24HourFormat(getContext(), mCurrentUserId);
+ if (is24) {
+ mCalendar.set(Calendar.HOUR_OF_DAY, hh);
+ } else {
+ mCalendar.set(Calendar.HOUR, hh);
}
- setText(getSmallTime());
- setContentDescription(mContentDescriptionFormat.format(mCalendar.getTime()));
+ mCalendar.set(Calendar.MINUTE, mm);
}
+ setText(getSmallTime());
+ setContentDescription(mContentDescriptionFormat.format(mCalendar.getTime()));
+ }
+
+ @Override
+ public void onDemoModeStarted() {
+ mDemoMode = true;
+ }
+
+ @Override
+ public void onDemoModeFinished() {
+ mDemoMode = false;
+ updateClock();
}
private final BroadcastReceiver mScreenReceiver = new BroadcastReceiver() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverControllerImpl.java
index 911715fdba63..8207012af6cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DataSaverControllerImpl.java
@@ -21,6 +21,8 @@ import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
+import androidx.annotation.NonNull;
+
import java.util.ArrayList;
public class DataSaverControllerImpl implements DataSaverController {
@@ -41,7 +43,8 @@ public class DataSaverControllerImpl implements DataSaverController {
}
}
- public void addCallback(Listener listener) {
+ @Override
+ public void addCallback(@NonNull Listener listener) {
synchronized (mListeners) {
mListeners.add(listener);
if (mListeners.size() == 1) {
@@ -51,7 +54,8 @@ public class DataSaverControllerImpl implements DataSaverController {
listener.onDataSaverChanged(isDataSaverEnabled());
}
- public void removeCallback(Listener listener) {
+ @Override
+ public void removeCallback(@NonNull Listener listener) {
synchronized (mListeners) {
mListeners.remove(listener);
if (mListeners.size() == 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
index 7280a881655c..071f05a962d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
@@ -24,6 +24,8 @@ import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.settings.CurrentUserTracker;
@@ -87,7 +89,7 @@ public class DeviceProvisionedControllerImpl extends CurrentUserTracker implemen
}
@Override
- public void addCallback(DeviceProvisionedListener listener) {
+ public void addCallback(@NonNull DeviceProvisionedListener listener) {
mListeners.add(listener);
if (mListeners.size() == 1) {
startListening(getCurrentUser());
@@ -97,7 +99,7 @@ public class DeviceProvisionedControllerImpl extends CurrentUserTracker implemen
}
@Override
- public void removeCallback(DeviceProvisionedListener listener) {
+ public void removeCallback(@NonNull DeviceProvisionedListener listener) {
mListeners.remove(listener);
if (mListeners.size() == 0) {
stopListening();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
index 41ff9d1029b2..659212c4d33d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
@@ -30,6 +30,8 @@ import android.provider.Settings.Secure;
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -123,7 +125,8 @@ public class FlashlightControllerImpl implements FlashlightController {
return mTorchAvailable;
}
- public void addCallback(FlashlightListener l) {
+ @Override
+ public void addCallback(@NonNull FlashlightListener l) {
synchronized (mListeners) {
if (mCameraId == null) {
tryInitCamera();
@@ -135,7 +138,8 @@ public class FlashlightControllerImpl implements FlashlightController {
}
}
- public void removeCallback(FlashlightListener l) {
+ @Override
+ public void removeCallback(@NonNull FlashlightListener l) {
synchronized (mListeners) {
cleanUpListenersLocked(l);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index 60ee75b534d8..1baed09d4e3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -30,6 +30,8 @@ import android.os.HandlerExecutor;
import android.os.UserManager;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import com.android.internal.util.ConcurrentUtils;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
@@ -143,7 +145,7 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof
* changes. It will immediately trigger the callback added to notify current state.
*/
@Override
- public void addCallback(Callback callback) {
+ public void addCallback(@NonNull Callback callback) {
synchronized (mCallbacks) {
if (callback == null || mCallbacks.contains(callback)) return;
if (DEBUG) Log.d(TAG, "addCallback " + callback);
@@ -163,7 +165,7 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof
}
@Override
- public void removeCallback(Callback callback) {
+ public void removeCallback(@NonNull Callback callback) {
if (callback == null) return;
if (DEBUG) Log.d(TAG, "removeCallback " + callback);
synchronized (mCallbacks) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index adfc14e1d72b..a995ade8dafe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -33,6 +33,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.android.systemui.BootCompleteCache;
@@ -87,12 +88,14 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio
/**
* Add a callback to listen for changes in location settings.
*/
- public void addCallback(LocationChangeCallback cb) {
+ @Override
+ public void addCallback(@NonNull LocationChangeCallback cb) {
mHandler.obtainMessage(H.MSG_ADD_CALLBACK, cb).sendToTarget();
mHandler.sendEmptyMessage(H.MSG_LOCATION_SETTINGS_CHANGED);
}
- public void removeCallback(LocationChangeCallback cb) {
+ @Override
+ public void removeCallback(@NonNull LocationChangeCallback cb) {
mHandler.obtainMessage(H.MSG_REMOVE_CALLBACK, cb).sendToTarget();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 95a97729936b..b790c92b293c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -22,7 +22,7 @@ import android.telephony.SubscriptionInfo;
import com.android.settingslib.net.DataUsageController;
import com.android.settingslib.wifi.AccessPoint;
-import com.android.systemui.DemoMode;
+import com.android.systemui.demomode.DemoMode;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import java.util.List;
@@ -30,8 +30,6 @@ import java.util.List;
public interface NetworkController extends CallbackController<SignalCallback>, DemoMode {
boolean hasMobileDataFeature();
- void addCallback(SignalCallback cb);
- void removeCallback(SignalCallback cb);
void setWifiEnabled(boolean enabled);
AccessPointController getAccessPointController();
DataUsageController getMobileDataController();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 32c4aec39923..7a0f69067851 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -55,14 +55,17 @@ import android.util.Log;
import android.util.MathUtils;
import android.util.SparseArray;
+import androidx.annotation.NonNull;
+
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.net.DataUsageController;
-import com.android.systemui.DemoMode;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.demomode.DemoMode;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -104,6 +107,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
private final DataSaverController mDataSaverController;
private final CurrentUserTracker mUserTracker;
private final BroadcastDispatcher mBroadcastDispatcher;
+ private final DemoModeController mDemoModeController;
private final Object mLock = new Object();
private Config mConfig;
@@ -173,11 +177,16 @@ public class NetworkControllerImpl extends BroadcastReceiver
* Construct this controller object and register for updates.
*/
@Inject
- public NetworkControllerImpl(Context context, @Background Looper bgLooper,
+ public NetworkControllerImpl(
+ Context context,
+ @Background Looper bgLooper,
DeviceProvisionedController deviceProvisionedController,
- BroadcastDispatcher broadcastDispatcher, ConnectivityManager connectivityManager,
- TelephonyManager telephonyManager, @Nullable WifiManager wifiManager,
- NetworkScoreManager networkScoreManager) {
+ BroadcastDispatcher broadcastDispatcher,
+ ConnectivityManager connectivityManager,
+ TelephonyManager telephonyManager,
+ @Nullable WifiManager wifiManager,
+ NetworkScoreManager networkScoreManager,
+ DemoModeController demoModeController) {
this(context, connectivityManager,
telephonyManager,
wifiManager,
@@ -188,7 +197,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
new DataUsageController(context),
new SubscriptionDefaults(),
deviceProvisionedController,
- broadcastDispatcher);
+ broadcastDispatcher,
+ demoModeController);
mReceiverHandler.post(mRegisterListeners);
}
@@ -202,7 +212,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
DataUsageController dataUsageController,
SubscriptionDefaults defaultsHandler,
DeviceProvisionedController deviceProvisionedController,
- BroadcastDispatcher broadcastDispatcher) {
+ BroadcastDispatcher broadcastDispatcher,
+ DemoModeController demoModeController) {
mContext = context;
mConfig = config;
mReceiverHandler = new Handler(bgLooper);
@@ -215,6 +226,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
mConnectivityManager = connectivityManager;
mHasMobileDataFeature =
mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+ mDemoModeController = demoModeController;
// telephony
mPhone = telephonyManager;
@@ -306,6 +318,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
doUpdateMobileControllers();
}
};
+
+ mDemoModeController.addCallback(this);
}
private final Runnable mClearForceValidated = () -> {
@@ -514,7 +528,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
mCallbackHandler.setEmergencyCallsOnly(mIsEmergency);
}
- public void addCallback(SignalCallback cb) {
+ @Override
+ public void addCallback(@NonNull SignalCallback cb) {
cb.setSubs(mCurrentSubscriptions);
cb.setIsAirplaneMode(new IconState(mAirplaneMode,
TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, mContext));
@@ -529,7 +544,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
}
@Override
- public void removeCallback(SignalCallback cb) {
+ public void removeCallback(@NonNull SignalCallback cb) {
mCallbackHandler.setListening(cb, false);
}
@@ -932,205 +947,217 @@ public class NetworkControllerImpl extends BroadcastReceiver
return "UNKNOWN_SOURCE";
}
- private boolean mDemoMode;
private boolean mDemoInetCondition;
private WifiSignalController.WifiState mDemoWifiState;
@Override
+ public void onDemoModeStarted() {
+ if (DEBUG) Log.d(TAG, "Entering demo mode");
+ unregisterListeners();
+ mDemoInetCondition = mInetCondition;
+ mDemoWifiState = mWifiSignalController.getState();
+ mDemoWifiState.ssid = "DemoMode";
+ }
+
+ @Override
+ public void onDemoModeFinished() {
+ if (DEBUG) Log.d(TAG, "Exiting demo mode");
+ // Update what MobileSignalControllers, because they may change
+ // to set the number of sim slots.
+ updateMobileControllers();
+ for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+ MobileSignalController controller = mMobileSignalControllers.valueAt(i);
+ controller.resetLastState();
+ }
+ mWifiSignalController.resetLastState();
+ mReceiverHandler.post(mRegisterListeners);
+ notifyAllListeners();
+ }
+
+ @Override
public void dispatchDemoCommand(String command, Bundle args) {
- if (!mDemoMode && command.equals(COMMAND_ENTER)) {
- if (DEBUG) Log.d(TAG, "Entering demo mode");
- unregisterListeners();
- mDemoMode = true;
- mDemoInetCondition = mInetCondition;
- mDemoWifiState = mWifiSignalController.getState();
- mDemoWifiState.ssid = "DemoMode";
- } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
- if (DEBUG) Log.d(TAG, "Exiting demo mode");
- mDemoMode = false;
- // Update what MobileSignalControllers, because they may change
- // to set the number of sim slots.
- updateMobileControllers();
+ if (!mDemoModeController.isInDemoMode()) {
+ return;
+ }
+
+ String airplane = args.getString("airplane");
+ if (airplane != null) {
+ boolean show = airplane.equals("show");
+ mCallbackHandler.setIsAirplaneMode(new IconState(show,
+ TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode,
+ mContext));
+ }
+ String fully = args.getString("fully");
+ if (fully != null) {
+ mDemoInetCondition = Boolean.parseBoolean(fully);
+ BitSet connected = new BitSet();
+
+ if (mDemoInetCondition) {
+ connected.set(mWifiSignalController.mTransportType);
+ }
+ mWifiSignalController.updateConnectivity(connected, connected);
for (int i = 0; i < mMobileSignalControllers.size(); i++) {
MobileSignalController controller = mMobileSignalControllers.valueAt(i);
- controller.resetLastState();
- }
- mWifiSignalController.resetLastState();
- mReceiverHandler.post(mRegisterListeners);
- notifyAllListeners();
- } else if (mDemoMode && command.equals(COMMAND_NETWORK)) {
- String airplane = args.getString("airplane");
- if (airplane != null) {
- boolean show = airplane.equals("show");
- mCallbackHandler.setIsAirplaneMode(new IconState(show,
- TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode,
- mContext));
- }
- String fully = args.getString("fully");
- if (fully != null) {
- mDemoInetCondition = Boolean.parseBoolean(fully);
- BitSet connected = new BitSet();
-
if (mDemoInetCondition) {
- connected.set(mWifiSignalController.mTransportType);
- }
- mWifiSignalController.updateConnectivity(connected, connected);
- for (int i = 0; i < mMobileSignalControllers.size(); i++) {
- MobileSignalController controller = mMobileSignalControllers.valueAt(i);
- if (mDemoInetCondition) {
- connected.set(controller.mTransportType);
- }
- controller.updateConnectivity(connected, connected);
+ connected.set(controller.mTransportType);
}
+ controller.updateConnectivity(connected, connected);
}
- String wifi = args.getString("wifi");
- if (wifi != null) {
- boolean show = wifi.equals("show");
- String level = args.getString("level");
- if (level != null) {
- mDemoWifiState.level = level.equals("null") ? -1
- : Math.min(Integer.parseInt(level), WifiIcons.WIFI_LEVEL_COUNT - 1);
- mDemoWifiState.connected = mDemoWifiState.level >= 0;
- }
- String activity = args.getString("activity");
- if (activity != null) {
- switch (activity) {
- case "inout":
- mWifiSignalController.setActivity(DATA_ACTIVITY_INOUT);
- break;
- case "in":
- mWifiSignalController.setActivity(DATA_ACTIVITY_IN);
- break;
- case "out":
- mWifiSignalController.setActivity(DATA_ACTIVITY_OUT);
- break;
- default:
- mWifiSignalController.setActivity(DATA_ACTIVITY_NONE);
- break;
- }
- } else {
- mWifiSignalController.setActivity(DATA_ACTIVITY_NONE);
- }
- String ssid = args.getString("ssid");
- if (ssid != null) {
- mDemoWifiState.ssid = ssid;
- }
- mDemoWifiState.enabled = show;
- mWifiSignalController.notifyListeners();
+ }
+ String wifi = args.getString("wifi");
+ if (wifi != null) {
+ boolean show = wifi.equals("show");
+ String level = args.getString("level");
+ if (level != null) {
+ mDemoWifiState.level = level.equals("null") ? -1
+ : Math.min(Integer.parseInt(level), WifiIcons.WIFI_LEVEL_COUNT - 1);
+ mDemoWifiState.connected = mDemoWifiState.level >= 0;
}
- String sims = args.getString("sims");
- if (sims != null) {
- int num = MathUtils.constrain(Integer.parseInt(sims), 1, 8);
- List<SubscriptionInfo> subs = new ArrayList<>();
- if (num != mMobileSignalControllers.size()) {
- mMobileSignalControllers.clear();
- int start = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
- for (int i = start /* get out of normal index range */; i < start + num; i++) {
- subs.add(addSignalController(i, i));
- }
- mCallbackHandler.setSubs(subs);
- for (int i = 0; i < mMobileSignalControllers.size(); i++) {
- int key = mMobileSignalControllers.keyAt(i);
- MobileSignalController controller = mMobileSignalControllers.get(key);
- controller.notifyListeners();
- }
+ String activity = args.getString("activity");
+ if (activity != null) {
+ switch (activity) {
+ case "inout":
+ mWifiSignalController.setActivity(DATA_ACTIVITY_INOUT);
+ break;
+ case "in":
+ mWifiSignalController.setActivity(DATA_ACTIVITY_IN);
+ break;
+ case "out":
+ mWifiSignalController.setActivity(DATA_ACTIVITY_OUT);
+ break;
+ default:
+ mWifiSignalController.setActivity(DATA_ACTIVITY_NONE);
+ break;
}
+ } else {
+ mWifiSignalController.setActivity(DATA_ACTIVITY_NONE);
}
- String nosim = args.getString("nosim");
- if (nosim != null) {
- mHasNoSubs = nosim.equals("show");
- mCallbackHandler.setNoSims(mHasNoSubs, mSimDetected);
+ String ssid = args.getString("ssid");
+ if (ssid != null) {
+ mDemoWifiState.ssid = ssid;
}
- String mobile = args.getString("mobile");
- if (mobile != null) {
- boolean show = mobile.equals("show");
- String datatype = args.getString("datatype");
- String slotString = args.getString("slot");
- int slot = TextUtils.isEmpty(slotString) ? 0 : Integer.parseInt(slotString);
- slot = MathUtils.constrain(slot, 0, 8);
- // Ensure we have enough sim slots
- List<SubscriptionInfo> subs = new ArrayList<>();
- while (mMobileSignalControllers.size() <= slot) {
- int nextSlot = mMobileSignalControllers.size();
- subs.add(addSignalController(nextSlot, nextSlot));
- }
- if (!subs.isEmpty()) {
- mCallbackHandler.setSubs(subs);
- }
- // Hack to index linearly for easy use.
- MobileSignalController controller = mMobileSignalControllers.valueAt(slot);
- controller.getState().dataSim = datatype != null;
- controller.getState().isDefault = datatype != null;
- controller.getState().dataConnected = datatype != null;
- if (datatype != null) {
- controller.getState().iconGroup =
- datatype.equals("1x") ? TelephonyIcons.ONE_X :
- datatype.equals("3g") ? TelephonyIcons.THREE_G :
- datatype.equals("4g") ? TelephonyIcons.FOUR_G :
- datatype.equals("4g+") ? TelephonyIcons.FOUR_G_PLUS :
- datatype.equals("5g") ? TelephonyIcons.NR_5G :
- datatype.equals("5ge") ? TelephonyIcons.LTE_CA_5G_E :
- datatype.equals("5g+") ? TelephonyIcons.NR_5G_PLUS :
- datatype.equals("e") ? TelephonyIcons.E :
- datatype.equals("g") ? TelephonyIcons.G :
- datatype.equals("h") ? TelephonyIcons.H :
- datatype.equals("h+") ? TelephonyIcons.H_PLUS :
- datatype.equals("lte") ? TelephonyIcons.LTE :
- datatype.equals("lte+") ? TelephonyIcons.LTE_PLUS :
- datatype.equals("dis") ? TelephonyIcons.DATA_DISABLED :
- datatype.equals("not") ? TelephonyIcons.NOT_DEFAULT_DATA :
- TelephonyIcons.UNKNOWN;
- }
- if (args.containsKey("roam")) {
- controller.getState().roaming = "show".equals(args.getString("roam"));
- }
- String level = args.getString("level");
- if (level != null) {
- controller.getState().level = level.equals("null") ? -1
- : Math.min(Integer.parseInt(level),
- CellSignalStrength.getNumSignalStrengthLevels());
- controller.getState().connected = controller.getState().level >= 0;
- }
- if (args.containsKey("inflate")) {
- for (int i = 0; i < mMobileSignalControllers.size(); i++) {
- mMobileSignalControllers.valueAt(i).mInflateSignalStrengths =
- "true".equals(args.getString("inflate"));
- }
+ mDemoWifiState.enabled = show;
+ mWifiSignalController.notifyListeners();
+ }
+ String sims = args.getString("sims");
+ if (sims != null) {
+ int num = MathUtils.constrain(Integer.parseInt(sims), 1, 8);
+ List<SubscriptionInfo> subs = new ArrayList<>();
+ if (num != mMobileSignalControllers.size()) {
+ mMobileSignalControllers.clear();
+ int start = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
+ for (int i = start /* get out of normal index range */; i < start + num; i++) {
+ subs.add(addSignalController(i, i));
}
- String activity = args.getString("activity");
- if (activity != null) {
- controller.getState().dataConnected = true;
- switch (activity) {
- case "inout":
- controller.setActivity(TelephonyManager.DATA_ACTIVITY_INOUT);
- break;
- case "in":
- controller.setActivity(TelephonyManager.DATA_ACTIVITY_IN);
- break;
- case "out":
- controller.setActivity(TelephonyManager.DATA_ACTIVITY_OUT);
- break;
- default:
- controller.setActivity(TelephonyManager.DATA_ACTIVITY_NONE);
- break;
- }
- } else {
- controller.setActivity(TelephonyManager.DATA_ACTIVITY_NONE);
+ mCallbackHandler.setSubs(subs);
+ for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+ int key = mMobileSignalControllers.keyAt(i);
+ MobileSignalController controller = mMobileSignalControllers.get(key);
+ controller.notifyListeners();
}
- controller.getState().enabled = show;
- controller.notifyListeners();
}
- String carrierNetworkChange = args.getString("carriernetworkchange");
- if (carrierNetworkChange != null) {
- boolean show = carrierNetworkChange.equals("show");
+ }
+ String nosim = args.getString("nosim");
+ if (nosim != null) {
+ mHasNoSubs = nosim.equals("show");
+ mCallbackHandler.setNoSims(mHasNoSubs, mSimDetected);
+ }
+ String mobile = args.getString("mobile");
+ if (mobile != null) {
+ boolean show = mobile.equals("show");
+ String datatype = args.getString("datatype");
+ String slotString = args.getString("slot");
+ int slot = TextUtils.isEmpty(slotString) ? 0 : Integer.parseInt(slotString);
+ slot = MathUtils.constrain(slot, 0, 8);
+ // Ensure we have enough sim slots
+ List<SubscriptionInfo> subs = new ArrayList<>();
+ while (mMobileSignalControllers.size() <= slot) {
+ int nextSlot = mMobileSignalControllers.size();
+ subs.add(addSignalController(nextSlot, nextSlot));
+ }
+ if (!subs.isEmpty()) {
+ mCallbackHandler.setSubs(subs);
+ }
+ // Hack to index linearly for easy use.
+ MobileSignalController controller = mMobileSignalControllers.valueAt(slot);
+ controller.getState().dataSim = datatype != null;
+ controller.getState().isDefault = datatype != null;
+ controller.getState().dataConnected = datatype != null;
+ if (datatype != null) {
+ controller.getState().iconGroup =
+ datatype.equals("1x") ? TelephonyIcons.ONE_X :
+ datatype.equals("3g") ? TelephonyIcons.THREE_G :
+ datatype.equals("4g") ? TelephonyIcons.FOUR_G :
+ datatype.equals("4g+") ? TelephonyIcons.FOUR_G_PLUS :
+ datatype.equals("5g") ? TelephonyIcons.NR_5G :
+ datatype.equals("5ge") ? TelephonyIcons.LTE_CA_5G_E :
+ datatype.equals("5g+") ? TelephonyIcons.NR_5G_PLUS :
+ datatype.equals("e") ? TelephonyIcons.E :
+ datatype.equals("g") ? TelephonyIcons.G :
+ datatype.equals("h") ? TelephonyIcons.H :
+ datatype.equals("h+") ? TelephonyIcons.H_PLUS :
+ datatype.equals("lte") ? TelephonyIcons.LTE :
+ datatype.equals("lte+") ? TelephonyIcons.LTE_PLUS :
+ datatype.equals("dis") ? TelephonyIcons.DATA_DISABLED :
+ datatype.equals("not") ? TelephonyIcons.NOT_DEFAULT_DATA :
+ TelephonyIcons.UNKNOWN;
+ }
+ if (args.containsKey("roam")) {
+ controller.getState().roaming = "show".equals(args.getString("roam"));
+ }
+ String level = args.getString("level");
+ if (level != null) {
+ controller.getState().level = level.equals("null") ? -1
+ : Math.min(Integer.parseInt(level),
+ CellSignalStrength.getNumSignalStrengthLevels());
+ controller.getState().connected = controller.getState().level >= 0;
+ }
+ if (args.containsKey("inflate")) {
for (int i = 0; i < mMobileSignalControllers.size(); i++) {
- MobileSignalController controller = mMobileSignalControllers.valueAt(i);
- controller.setCarrierNetworkChangeMode(show);
+ mMobileSignalControllers.valueAt(i).mInflateSignalStrengths =
+ "true".equals(args.getString("inflate"));
}
}
+ String activity = args.getString("activity");
+ if (activity != null) {
+ controller.getState().dataConnected = true;
+ switch (activity) {
+ case "inout":
+ controller.setActivity(TelephonyManager.DATA_ACTIVITY_INOUT);
+ break;
+ case "in":
+ controller.setActivity(TelephonyManager.DATA_ACTIVITY_IN);
+ break;
+ case "out":
+ controller.setActivity(TelephonyManager.DATA_ACTIVITY_OUT);
+ break;
+ default:
+ controller.setActivity(TelephonyManager.DATA_ACTIVITY_NONE);
+ break;
+ }
+ } else {
+ controller.setActivity(TelephonyManager.DATA_ACTIVITY_NONE);
+ }
+ controller.getState().enabled = show;
+ controller.notifyListeners();
+ }
+ String carrierNetworkChange = args.getString("carriernetworkchange");
+ if (carrierNetworkChange != null) {
+ boolean show = carrierNetworkChange.equals("show");
+ for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+ MobileSignalController controller = mMobileSignalControllers.valueAt(i);
+ controller.setCarrierNetworkChangeMode(show);
+ }
}
}
+ @Override
+ public List<String> demoCommands() {
+ List<String> s = new ArrayList<>();
+ s.add(DemoMode.COMMAND_NETWORK);
+ return s;
+ }
+
private SubscriptionInfo addSignalController(int id, int simSlotIndex) {
SubscriptionInfo info = new SubscriptionInfo(id, "", simSlotIndex, "", "", 0, 0, "", 0,
null, null, null, "", false, null, null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java
index 288b3aff2af6..604e76e46ab5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NextAlarmControllerImpl.java
@@ -23,6 +23,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.UserHandle;
+import androidx.annotation.NonNull;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -59,12 +61,14 @@ public class NextAlarmControllerImpl extends BroadcastReceiver
pw.print(" mNextAlarm="); pw.println(mNextAlarm);
}
- public void addCallback(NextAlarmChangeCallback cb) {
+ @Override
+ public void addCallback(@NonNull NextAlarmChangeCallback cb) {
mChangeCallbacks.add(cb);
cb.onNextAlarmChanged(mNextAlarm);
}
- public void removeCallback(NextAlarmChangeCallback cb) {
+ @Override
+ public void removeCallback(@NonNull NextAlarmChangeCallback cb) {
mChangeCallbacks.remove(cb);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockControllerImpl.java
index 1f368e164678..58bb64bbba5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockControllerImpl.java
@@ -19,6 +19,8 @@ package com.android.systemui.statusbar.policy;
import android.content.Context;
import android.os.UserHandle;
+import androidx.annotation.NonNull;
+
import com.android.internal.view.RotationPolicy;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -47,12 +49,14 @@ public final class RotationLockControllerImpl implements RotationLockController
setListening(true);
}
- public void addCallback(RotationLockControllerCallback callback) {
+ @Override
+ public void addCallback(@NonNull RotationLockControllerCallback callback) {
mCallbacks.add(callback);
notifyChanged(callback);
}
- public void removeCallback(RotationLockControllerCallback callback) {
+ @Override
+ public void removeCallback(@NonNull RotationLockControllerCallback callback) {
mCallbacks.remove(callback);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 309d4b04ebbf..d1a7a7b07a65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -42,6 +42,8 @@ import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
+import androidx.annotation.NonNull;
+
import com.android.internal.annotations.GuardedBy;
import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig;
@@ -274,7 +276,7 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi
}
@Override
- public void removeCallback(SecurityControllerCallback callback) {
+ public void removeCallback(@NonNull SecurityControllerCallback callback) {
synchronized (mCallbacks) {
if (callback == null) return;
if (DEBUG) Log.d(TAG, "removeCallback " + callback);
@@ -283,7 +285,7 @@ public class SecurityControllerImpl extends CurrentUserTracker implements Securi
}
@Override
- public void addCallback(SecurityControllerCallback callback) {
+ public void addCallback(@NonNull SecurityControllerCallback callback) {
synchronized (mCallbacks) {
if (callback == null || mCallbacks.contains(callback)) return;
if (DEBUG) Log.d(TAG, "addCallback " + callback);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyControllerImpl.java
index 5db66932d3c1..cbafedc40d7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensorPrivacyControllerImpl.java
@@ -19,6 +19,8 @@ package com.android.systemui.statusbar.policy;
import android.content.Context;
import android.hardware.SensorPrivacyManager;
+import androidx.annotation.NonNull;
+
import java.util.ArrayList;
import java.util.List;
@@ -60,7 +62,7 @@ public class SensorPrivacyControllerImpl implements SensorPrivacyController,
/**
* Adds the provided listener for callbacks when sensor privacy state changes.
*/
- public void addCallback(OnSensorPrivacyChangedListener listener) {
+ public void addCallback(@NonNull OnSensorPrivacyChangedListener listener) {
synchronized (mLock) {
mListeners.add(listener);
notifyListenerLocked(listener);
@@ -70,7 +72,7 @@ public class SensorPrivacyControllerImpl implements SensorPrivacyController,
/**
* Removes the provided listener from callbacks when sensor privacy state changes.
*/
- public void removeCallback(OnSensorPrivacyChangedListener listener) {
+ public void removeCallback(@NonNull OnSensorPrivacyChangedListener listener) {
synchronized (mLock) {
mListeners.remove(listener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
index 0ca6ff6ec66e..6b2820d8d97d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoControllerImpl.java
@@ -34,6 +34,8 @@ import android.os.UserManager;
import android.provider.ContactsContract;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import com.android.internal.util.UserIcons;
import com.android.settingslib.drawable.UserIconDrawable;
import com.android.systemui.R;
@@ -75,12 +77,14 @@ public class UserInfoControllerImpl implements UserInfoController {
null, null);
}
- public void addCallback(OnUserInfoChangedListener callback) {
+ @Override
+ public void addCallback(@NonNull OnUserInfoChangedListener callback) {
mCallbacks.add(callback);
callback.onUserInfoChanged(mUserName, mUserDrawable, mUserAccount);
}
- public void removeCallback(OnUserInfoChangedListener callback) {
+ @Override
+ public void removeCallback(@NonNull OnUserInfoChangedListener callback) {
mCallbacks.remove(callback);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index 4376a0145826..75c1e33203b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -37,6 +37,8 @@ import android.service.notification.ZenModeConfig.ZenRule;
import android.text.format.DateFormat;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dumpable;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -124,14 +126,14 @@ public class ZenModeControllerImpl extends CurrentUserTracker
}
@Override
- public void addCallback(Callback callback) {
+ public void addCallback(@NonNull Callback callback) {
synchronized (mCallbacksLock) {
mCallbacks.add(callback);
}
}
@Override
- public void removeCallback(Callback callback) {
+ public void removeCallback(@NonNull Callback callback) {
synchronized (mCallbacksLock) {
mCallbacks.remove(callback);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java
index e3eed35f0483..d4c6f4d6232a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/micdisclosure/AudioRecordingDisclosureBar.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.tv.micdisclosure;
+import static android.provider.DeviceConfig.NAMESPACE_PRIVACY;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import android.animation.Animator;
@@ -27,9 +28,8 @@ import android.annotation.UiThread;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.database.ContentObserver;
import android.graphics.PixelFormat;
-import android.provider.Settings;
+import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
@@ -46,7 +46,9 @@ import com.android.systemui.statusbar.tv.TvStatusBar;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
+import java.util.Collections;
import java.util.LinkedList;
+import java.util.List;
import java.util.Queue;
import java.util.Set;
@@ -65,9 +67,9 @@ public class AudioRecordingDisclosureBar implements
// CtsSystemUiHostTestCases:TvMicrophoneCaptureIndicatorTest
private static final String LAYOUT_PARAMS_TITLE = "MicrophoneCaptureIndicator";
- private static final String ENABLE_FLAG = "sysui_mic_disclosure_enable";
- private static final String EXEMPT_PACKAGES_LIST = "sysui_mic_disclosure_exempt";
- private static final String FORCED_PACKAGES_LIST = "sysui_mic_disclosure_forced";
+ private static final String ENABLED_FLAG = "mic_disclosure_enabled";
+ private static final String EXEMPT_PACKAGES_LIST = "mic_disclosure_exempt_packages";
+ private static final String FORCED_PACKAGES_LIST = "mic_disclosure_forced_packages";
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"STATE_"}, value = {
@@ -95,7 +97,7 @@ public class AudioRecordingDisclosureBar implements
private static final int MAXIMIZED_DURATION = 3000;
private final Context mContext;
- private boolean mIsEnabledInSettings;
+ private boolean mIsEnabled;
private View mIndicatorView;
private View mIconTextsContainer;
@@ -141,26 +143,37 @@ public class AudioRecordingDisclosureBar implements
* Set of applications for which we make an exception and do not show the indicator. This gets
* populated once - in {@link #AudioRecordingDisclosureBar(Context)}.
*/
- private final Set<String> mExemptPackages;
+ private final Set<String> mExemptPackages = new ArraySet<>();
public AudioRecordingDisclosureBar(Context context) {
mContext = context;
- // Loading configs
+ // Load configs
mRevealRecordingPackages = mContext.getResources().getBoolean(
R.bool.audio_recording_disclosure_reveal_packages);
- mExemptPackages = new ArraySet<>(
- Arrays.asList(mContext.getResources().getStringArray(
- R.array.audio_recording_disclosure_exempt_apps)));
- mExemptPackages.addAll(Arrays.asList(getGlobalStringArray(EXEMPT_PACKAGES_LIST)));
- mExemptPackages.removeAll(Arrays.asList(getGlobalStringArray(FORCED_PACKAGES_LIST)));
-
- // Check setting, and start if enabled
- mIsEnabledInSettings = checkIfEnabledInSettings();
- registerSettingsObserver();
- if (mIsEnabledInSettings) {
+ reloadExemptPackages();
+
+ mIsEnabled = DeviceConfig.getBoolean(NAMESPACE_PRIVACY, ENABLED_FLAG, true);
+ // Start if enabled
+ if (mIsEnabled) {
start();
}
+
+ // Set up a config change listener
+ DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_PRIVACY, mContext.getMainExecutor(),
+ mConfigChangeListener);
+ }
+
+ private void reloadExemptPackages() {
+ mExemptPackages.clear();
+ mExemptPackages.addAll(Arrays.asList(mContext.getResources().getStringArray(
+ R.array.audio_recording_disclosure_exempt_apps)));
+ mExemptPackages.addAll(
+ splitByComma(
+ DeviceConfig.getString(NAMESPACE_PRIVACY, EXEMPT_PACKAGES_LIST, null)));
+ mExemptPackages.removeAll(
+ splitByComma(
+ DeviceConfig.getString(NAMESPACE_PRIVACY, FORCED_PACKAGES_LIST, null)));
}
@UiThread
@@ -485,13 +498,11 @@ public class AudioRecordingDisclosureBar implements
mState = STATE_MINIMIZED;
- if (mRevealRecordingPackages) {
- if (!mPendingNotificationPackages.isEmpty()) {
- // There is a new application that started recording, tell the user about it.
- expand(mPendingNotificationPackages.poll());
- } else {
- hideIndicatorIfNeeded();
- }
+ if (mRevealRecordingPackages && !mPendingNotificationPackages.isEmpty()) {
+ // There is a new application that started recording, tell the user about it.
+ expand(mPendingNotificationPackages.poll());
+ } else {
+ hideIndicatorIfNeeded();
}
}
@@ -525,11 +536,6 @@ public class AudioRecordingDisclosureBar implements
mBgEnd = null;
}
- private String[] getGlobalStringArray(String setting) {
- String result = Settings.Global.getString(mContext.getContentResolver(), setting);
- return TextUtils.isEmpty(result) ? new String[0] : result.split(",");
- }
-
private String getApplicationLabel(String packageName) {
assertRevealingRecordingPackages();
@@ -550,32 +556,26 @@ public class AudioRecordingDisclosureBar implements
}
}
- private boolean checkIfEnabledInSettings() {
- // 0 = disabled, everything else = enabled. Enabled by default.
- return Settings.Global.getInt(mContext.getContentResolver(),
- ENABLE_FLAG, 1) != 0;
+ private static List<String> splitByComma(String string) {
+ return TextUtils.isEmpty(string) ? Collections.emptyList() : Arrays.asList(
+ string.split(","));
}
- private void registerSettingsObserver() {
- final ContentObserver contentObserver = new ContentObserver(
- mContext.getMainThreadHandler()) {
- @Override
- public void onChange(boolean selfChange) {
- if (mIsEnabledInSettings == checkIfEnabledInSettings()) {
- // Nothing changed as we know it - ignore.
- return;
- }
-
- // Things changed: flip the flag.
- mIsEnabledInSettings = !mIsEnabledInSettings;
- if (mIsEnabledInSettings) {
- start();
- } else {
- stop();
+ private final DeviceConfig.OnPropertiesChangedListener mConfigChangeListener =
+ new DeviceConfig.OnPropertiesChangedListener() {
+ @Override
+ public void onPropertiesChanged(DeviceConfig.Properties properties) {
+ reloadExemptPackages();
+
+ // Check if was enabled/disabled
+ if (mIsEnabled != properties.getBoolean(ENABLED_FLAG, true)) {
+ mIsEnabled = !mIsEnabled;
+ if (mIsEnabled) {
+ start();
+ } else {
+ stop();
+ }
+ }
}
- }
- };
- mContext.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(ENABLE_FLAG), false, contentObserver);
- }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
index 49ada1a5e41e..1f444340653d 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
@@ -15,14 +15,10 @@
*/
package com.android.systemui.tuner;
-import android.content.ContentResolver;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
-import android.database.ContentObserver;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.provider.Settings;
import android.view.MenuItem;
import androidx.preference.Preference;
@@ -33,13 +29,13 @@ import androidx.preference.SwitchPreference;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.DemoMode;
import com.android.systemui.R;
+import com.android.systemui.demomode.DemoMode;
+import com.android.systemui.demomode.DemoModeAvailabilityTracker;
+import com.android.systemui.demomode.DemoModeController;
public class DemoModeFragment extends PreferenceFragment implements OnPreferenceChangeListener {
- private static final String DEMO_MODE_ON = "sysui_tuner_demo_on";
-
private static final String[] STATUS_ICONS = {
"volume",
"bluetooth",
@@ -57,6 +53,17 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference
private SwitchPreference mEnabledSwitch;
private SwitchPreference mOnSwitch;
+ private DemoModeController mDemoModeController;
+ private Tracker mDemoModeTracker;
+
+ // We are the only ones who ever call this constructor, so don't worry about the warning
+ @SuppressLint("ValidFragment")
+ public DemoModeFragment(DemoModeController demoModeController) {
+ super();
+ mDemoModeController = demoModeController;
+ }
+
+
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
Context context = getContext();
@@ -73,13 +80,11 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference
screen.addPreference(mOnSwitch);
setPreferenceScreen(screen);
+ mDemoModeTracker = new Tracker(context);
+ mDemoModeTracker.startTracking();
updateDemoModeEnabled();
updateDemoModeOn();
- ContentResolver contentResolver = getContext().getContentResolver();
- contentResolver.registerContentObserver(Settings.Global.getUriFor(
- DemoMode.DEMO_MODE_ALLOWED), false, mDemoModeObserver);
- contentResolver.registerContentObserver(Settings.Global.getUriFor(DEMO_MODE_ON), false,
- mDemoModeObserver);
+
setHasOptionsMenu(true);
}
@@ -107,21 +112,17 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference
@Override
public void onDestroy() {
- getContext().getContentResolver().unregisterContentObserver(mDemoModeObserver);
+ mDemoModeTracker.stopTracking();
super.onDestroy();
}
private void updateDemoModeEnabled() {
- boolean enabled = Settings.Global.getInt(getContext().getContentResolver(),
- DemoMode.DEMO_MODE_ALLOWED, 0) != 0;
- mEnabledSwitch.setChecked(enabled);
- mOnSwitch.setEnabled(enabled);
+ mEnabledSwitch.setChecked(mDemoModeTracker.isDemoModeAvailable());
+ mOnSwitch.setEnabled(mDemoModeTracker.isDemoModeAvailable());
}
private void updateDemoModeOn() {
- boolean enabled = Settings.Global.getInt(getContext().getContentResolver(),
- DEMO_MODE_ON, 0) != 0;
- mOnSwitch.setChecked(enabled);
+ mOnSwitch.setChecked(mDemoModeTracker.isInDemoMode());
}
@Override
@@ -134,7 +135,7 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference
stopDemoMode();
}
MetricsLogger.action(getContext(), MetricsEvent.TUNER_DEMO_MODE_ENABLED, enabled);
- setGlobal(DemoMode.DEMO_MODE_ALLOWED, enabled ? 1 : 0);
+ mDemoModeController.requestSetDemoModeAllowed(enabled);
} else if (preference == mOnSwitch) {
MetricsLogger.action(getContext(), MetricsEvent.TUNER_DEMO_MODE_ON, enabled);
if (enabled) {
@@ -151,11 +152,11 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference
private void startDemoMode() {
Intent intent = new Intent(DemoMode.ACTION_DEMO);
- intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_ENTER);
- getContext().sendBroadcast(intent);
+ mDemoModeController.requestStartDemoMode();
intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_CLOCK);
+ //TODO: everything below should move to DemoModeController, or some `initialState` command
String demoTime = "1010"; // 10:10, a classic choice of horologists
try {
String[] versionParts = android.os.Build.VERSION.RELEASE_OR_CODENAME.split("\\.");
@@ -194,25 +195,31 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference
intent.putExtra("visible", "false");
getContext().sendBroadcast(intent);
- setGlobal(DEMO_MODE_ON, 1);
}
private void stopDemoMode() {
- Intent intent = new Intent(DemoMode.ACTION_DEMO);
- intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_EXIT);
- getContext().sendBroadcast(intent);
- setGlobal(DEMO_MODE_ON, 0);
+ mDemoModeController.requestFinishDemoMode();
}
- private void setGlobal(String key, int value) {
- Settings.Global.putInt(getContext().getContentResolver(), key, value);
- }
+ private class Tracker extends DemoModeAvailabilityTracker {
+ Tracker(Context context) {
+ super(context);
+ }
- private final ContentObserver mDemoModeObserver =
- new ContentObserver(new Handler(Looper.getMainLooper())) {
- public void onChange(boolean selfChange) {
+ @Override
+ public void onDemoModeAvailabilityChanged() {
updateDemoModeEnabled();
updateDemoModeOn();
- };
+ }
+
+ @Override
+ public void onDemoModeStarted() {
+ updateDemoModeOn();
+ }
+
+ @Override
+ public void onDemoModeFinished() {
+ updateDemoModeOn();
+ }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
index fa531b5243b4..87d2063d18e9 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
@@ -14,18 +14,18 @@
package com.android.systemui.tuner;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_CODE_END;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_CODE_START;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.KEY_IMAGE_DELIM;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.MENU_IME_ROTATE;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAVSPACE;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_LEFT;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_RIGHT;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.NAV_BAR_VIEWS;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractButton;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractImage;
-import static com.android.systemui.statusbar.phone.NavigationBarInflaterView.extractKeycode;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_CODE_END;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_CODE_START;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_IMAGE_DELIM;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.MENU_IME_ROTATE;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAVSPACE;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_LEFT;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_RIGHT;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_VIEWS;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractButton;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractImage;
+import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractKeycode;
import android.annotation.Nullable;
import android.app.AlertDialog;
@@ -51,6 +51,7 @@ import com.android.systemui.tuner.TunerService.Tunable;
import java.util.ArrayList;
+@Deprecated
public class NavBarTuner extends TunerPreferenceFragment {
private static final String LAYOUT = "layout";
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index 453c2f7da71f..78341edefbb2 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -31,6 +31,7 @@ import androidx.preference.PreferenceScreen;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.fragments.FragmentService;
import javax.inject.Inject;
@@ -41,9 +42,12 @@ public class TunerActivity extends Activity implements
private static final String TAG_TUNER = "tuner";
+ private final DemoModeController mDemoModeController;
+
@Inject
- TunerActivity() {
+ TunerActivity(DemoModeController demoModeController) {
super();
+ mDemoModeController = demoModeController;
}
protected void onCreate(Bundle savedInstanceState) {
@@ -61,7 +65,8 @@ public class TunerActivity extends Activity implements
final String action = getIntent().getAction();
boolean showDemoMode = action != null && action.equals(
"com.android.settings.action.DEMO_MODE");
- final PreferenceFragment fragment = showDemoMode ? new DemoModeFragment()
+ final PreferenceFragment fragment = showDemoMode
+ ? new DemoModeFragment(mDemoModeController)
: new TunerFragment();
getFragmentManager().beginTransaction().replace(R.id.content_frame,
fragment, TAG_TUNER).commit();
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 644f7582f146..12dced7cc7b1 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -18,7 +18,6 @@ package com.android.systemui.tuner;
import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.net.Uri;
@@ -33,9 +32,9 @@ import android.util.ArraySet;
import com.android.internal.util.ArrayUtils;
import com.android.systemui.DejankUtils;
-import com.android.systemui.DemoMode;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -54,6 +53,7 @@ import javax.inject.Singleton;
@Singleton
public class TunerServiceImpl extends TunerService {
+ private static final String TAG = "TunerService";
private static final String TUNER_VERSION = "sysui_tuner_version";
private static final int CURRENT_TUNER_VERSION = 4;
@@ -63,7 +63,8 @@ public class TunerServiceImpl extends TunerService {
private static final String[] RESET_EXCEPTION_LIST = new String[] {
QSTileHost.TILES_SETTING,
Settings.Secure.DOZE_ALWAYS_ON,
- Settings.Secure.MEDIA_CONTROLS_RESUME
+ Settings.Secure.MEDIA_CONTROLS_RESUME,
+ Secure.MEDIA_CONTROLS_RESUME_BLOCKED
};
private final Observer mObserver = new Observer();
@@ -76,6 +77,7 @@ public class TunerServiceImpl extends TunerService {
private final HashSet<Tunable> mTunables = LeakDetector.ENABLED ? new HashSet<>() : null;
private final Context mContext;
private final LeakDetector mLeakDetector;
+ private final DemoModeController mDemoModeController;
private ContentResolver mContentResolver;
private int mCurrentUser;
@@ -84,11 +86,16 @@ public class TunerServiceImpl extends TunerService {
/**
*/
@Inject
- public TunerServiceImpl(Context context, @Main Handler mainHandler,
- LeakDetector leakDetector, BroadcastDispatcher broadcastDispatcher) {
+ public TunerServiceImpl(
+ Context context,
+ @Main Handler mainHandler,
+ LeakDetector leakDetector,
+ DemoModeController demoModeController,
+ BroadcastDispatcher broadcastDispatcher) {
mContext = context;
mContentResolver = mContext.getContentResolver();
mLeakDetector = leakDetector;
+ mDemoModeController = demoModeController;
for (UserInfo user : UserManager.get(mContext).getUsers()) {
mCurrentUser = user.getUserHandle().getIdentifier();
@@ -244,12 +251,11 @@ public class TunerServiceImpl extends TunerService {
}
public void clearAllFromUser(int user) {
- // A couple special cases.
- Settings.Global.putString(mContentResolver, DemoMode.DEMO_MODE_ALLOWED, null);
- Intent intent = new Intent(DemoMode.ACTION_DEMO);
- intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_EXIT);
- mContext.sendBroadcast(intent);
+ // Turn off demo mode
+ mDemoModeController.requestFinishDemoMode();
+ mDemoModeController.requestSetDemoModeAllowed(false);
+ // A couple special cases.
for (String key : mTunableLookup.keySet()) {
if (ArrayUtils.contains(RESET_EXCEPTION_LIST, key)) {
continue;
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIRootComponent.java b/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
index dce38c109930..fd6ba1a6af0e 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIRootComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvGlobalRootComponent.java
@@ -19,11 +19,10 @@ package com.android.systemui.tv;
import com.android.systemui.dagger.DefaultComponentBinder;
import com.android.systemui.dagger.DependencyBinder;
import com.android.systemui.dagger.DependencyProvider;
+import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SystemServicesModule;
import com.android.systemui.dagger.SystemUIBinder;
-import com.android.systemui.dagger.SystemUIDefaultModule;
import com.android.systemui.dagger.SystemUIModule;
-import com.android.systemui.dagger.SystemUIRootComponent;
import com.android.systemui.onehanded.dagger.OneHandedModule;
import javax.inject.Singleton;
@@ -42,14 +41,17 @@ import dagger.Component;
SystemServicesModule.class,
SystemUIBinder.class,
SystemUIModule.class,
- SystemUIDefaultModule.class,
+ TvSystemUIModule.class,
TvSystemUIBinder.class})
-public interface TvSystemUIRootComponent extends SystemUIRootComponent {
+public interface TvGlobalRootComponent extends GlobalRootComponent {
/**
* Component Builder interface. This allows to bind Context instance in the component
*/
@Component.Builder
- interface Builder extends SystemUIRootComponent.Builder {
- TvSystemUIRootComponent build();
+ interface Builder extends GlobalRootComponent.Builder {
+ TvGlobalRootComponent build();
}
+
+ @Override
+ TvSysUIComponent.Builder getSysUIComponent();
}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponent.java b/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponent.java
new file mode 100644
index 000000000000..bc0cb51c64a3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSysUIComponent.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 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.tv;
+
+import com.android.systemui.dagger.SysUIComponent;
+import com.android.systemui.dagger.SysUISingleton;
+
+import dagger.Subcomponent;
+
+/**
+ * Dagger Subcomponent for Core SysUI.
+ */
+@SysUISingleton
+@Subcomponent(modules = {})
+public interface TvSysUIComponent extends SysUIComponent {
+
+ /**
+ * Builder for a SysUIComponent.
+ */
+ @Subcomponent.Builder
+ interface Builder extends SysUIComponent.Builder {
+ TvSysUIComponent build();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java
index be30a4a4c72e..9a44bf12a3ef 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java
@@ -16,7 +16,7 @@
package com.android.systemui.tv;
-import com.android.systemui.dagger.SystemUIRootComponent;
+import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.pip.tv.dagger.PipModule;
import dagger.Binds;
@@ -25,5 +25,5 @@ import dagger.Module;
@Module(includes = {PipModule.class})
interface TvSystemUIBinder {
@Binds
- SystemUIRootComponent bindSystemUIRootComponent(TvSystemUIRootComponent systemUIRootComponent);
+ GlobalRootComponent bindGlobalRootComponent(TvGlobalRootComponent globalRootComponent);
}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java
index 7d3ec678fd5f..c99ad23ab23d 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java
@@ -19,16 +19,16 @@ package com.android.systemui.tv;
import android.content.Context;
import com.android.systemui.SystemUIFactory;
-import com.android.systemui.dagger.SystemUIRootComponent;
+import com.android.systemui.dagger.GlobalRootComponent;
/**
- * TV variant {@link SystemUIFactory}, that substitutes default {@link SystemUIRootComponent} for
- * {@link TvSystemUIRootComponent}
+ * TV variant {@link SystemUIFactory}, that substitutes default {@link GlobalRootComponent} for
+ * {@link TvGlobalRootComponent}
*/
public class TvSystemUIFactory extends SystemUIFactory {
@Override
- protected SystemUIRootComponent buildSystemUIRootComponent(Context context) {
- return DaggerTvSystemUIRootComponent.builder()
+ protected GlobalRootComponent buildGlobalRootComponent(Context context) {
+ return DaggerTvGlobalRootComponent.builder()
.context(context)
.build();
}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
new file mode 100644
index 000000000000..0baecd51653f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2019 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.tv;
+
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.PowerManager;
+
+import androidx.annotation.Nullable;
+
+import com.android.keyguard.KeyguardViewController;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.dock.DockManager;
+import com.android.systemui.dock.DockManagerImpl;
+import com.android.systemui.doze.DozeHost;
+import com.android.systemui.plugins.qs.QSFactory;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.power.EnhancedEstimates;
+import com.android.systemui.power.EnhancedEstimatesImpl;
+import com.android.systemui.qs.dagger.QSModule;
+import com.android.systemui.qs.tileimpl.QSFactoryImpl;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsImplementation;
+import com.android.systemui.stackdivider.DividerModule;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.phone.DozeServiceHost;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.ShadeControllerImpl;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BatteryControllerImpl;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.wmshell.WindowManagerShellModule;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * A dagger module for injecting default implementations of components of System UI that may be
+ * overridden by the System UI implementation.
+ */
+@Module(includes = {
+ DividerModule.class,
+ QSModule.class,
+ WindowManagerShellModule.class
+ },
+ subcomponents = {
+ TvSysUIComponent.class
+ })
+public abstract class TvSystemUIModule {
+
+ @Singleton
+ @Provides
+ @Named(LEAK_REPORT_EMAIL_NAME)
+ @Nullable
+ static String provideLeakReportEmail() {
+ return null;
+ }
+
+ @Binds
+ abstract EnhancedEstimates bindEnhancedEstimates(EnhancedEstimatesImpl enhancedEstimates);
+
+ @Binds
+ abstract NotificationLockscreenUserManager bindNotificationLockscreenUserManager(
+ NotificationLockscreenUserManagerImpl notificationLockscreenUserManager);
+
+ @Provides
+ @Singleton
+ static BatteryController provideBatteryController(Context context,
+ EnhancedEstimates enhancedEstimates, PowerManager powerManager,
+ BroadcastDispatcher broadcastDispatcher, DemoModeController demoModeController,
+ @Main Handler mainHandler, @Background Handler bgHandler) {
+ BatteryController bC = new BatteryControllerImpl(context, enhancedEstimates, powerManager,
+ broadcastDispatcher, demoModeController, mainHandler, bgHandler);
+ bC.init();
+ return bC;
+ }
+
+ @Binds
+ @Singleton
+ abstract QSFactory bindQSFactory(QSFactoryImpl qsFactoryImpl);
+
+ @Binds
+ abstract DockManager bindDockManager(DockManagerImpl dockManager);
+
+ @Binds
+ abstract NotificationEntryManager.KeyguardEnvironment bindKeyguardEnvironment(
+ KeyguardEnvironmentImpl keyguardEnvironment);
+
+ @Binds
+ abstract ShadeController provideShadeController(ShadeControllerImpl shadeController);
+
+ @Singleton
+ @Provides
+ @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
+ static boolean provideAllowNotificationLongPress() {
+ return true;
+ }
+
+ @Singleton
+ @Provides
+ static HeadsUpManagerPhone provideHeadsUpManagerPhone(
+ Context context,
+ StatusBarStateController statusBarStateController,
+ KeyguardBypassController bypassController,
+ NotificationGroupManager groupManager,
+ ConfigurationController configurationController) {
+ return new HeadsUpManagerPhone(context, statusBarStateController, bypassController,
+ groupManager, configurationController);
+ }
+
+ @Binds
+ abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone);
+
+ @Provides
+ @Singleton
+ static Recents provideRecents(Context context, RecentsImplementation recentsImplementation,
+ CommandQueue commandQueue) {
+ return new Recents(context, recentsImplementation, commandQueue);
+ }
+
+ @Binds
+ abstract DeviceProvisionedController bindDeviceProvisionedController(
+ DeviceProvisionedControllerImpl deviceProvisionedController);
+
+ @Binds
+ abstract KeyguardViewController bindKeyguardViewController(
+ StatusBarKeyguardViewManager statusBarKeyguardViewManager);
+
+ @Binds
+ abstract DozeHost provideDozeHost(DozeServiceHost dozeServiceHost);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index d16bedcad960..c82b39af4ab3 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -23,16 +23,13 @@ import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
-import com.android.keyguard.KeyguardClockSwitch;
import com.android.keyguard.KeyguardMessageArea;
import com.android.keyguard.KeyguardSliceView;
-import com.android.systemui.dagger.SystemUIRootComponent;
import com.android.systemui.qs.QSFooterImpl;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.qs.QuickQSPanel;
import com.android.systemui.qs.QuickStatusBarHeader;
import com.android.systemui.qs.customize.QSCustomizer;
-import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import java.lang.reflect.InvocationTargetException;
@@ -43,8 +40,7 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
-import dagger.Module;
-import dagger.Provides;
+import dagger.BindsInstance;
import dagger.Subcomponent;
/**
@@ -55,24 +51,16 @@ import dagger.Subcomponent;
public class InjectionInflationController {
public static final String VIEW_CONTEXT = "view_context";
- private final ViewCreator mViewCreator;
private final ArrayMap<String, Method> mInjectionMap = new ArrayMap<>();
private final LayoutInflater.Factory2 mFactory = new InjectionFactory();
+ private final ViewInstanceCreator.Factory mViewInstanceCreatorFactory;
@Inject
- public InjectionInflationController(SystemUIRootComponent rootComponent) {
- mViewCreator = rootComponent.createViewCreator();
+ public InjectionInflationController(ViewInstanceCreator.Factory viewInstanceCreatorFactory) {
+ mViewInstanceCreatorFactory = viewInstanceCreatorFactory;
initInjectionMap();
}
- ArrayMap<String, Method> getInjectionMap() {
- return mInjectionMap;
- }
-
- ViewCreator getFragmentCreator() {
- return mViewCreator;
- }
-
/**
* Wraps a {@link LayoutInflater} to support creating dagger injected views.
* See docs/dagger.md for details.
@@ -93,25 +81,19 @@ public class InjectionInflationController {
}
/**
- * The subcomponent of dagger that holds all views that need injection.
+ * Subcomponent that actually creates injected views.
*/
@Subcomponent
- public interface ViewCreator {
- /**
- * Creates another subcomponent to actually generate the view.
- */
- ViewInstanceCreator createInstanceCreator(ViewAttributeProvider attributeProvider);
- }
-
- /**
- * Secondary sub-component that actually creates the views.
- *
- * Having two subcomponents lets us hide the complexity of providing the named context
- * and AttributeSet from the SystemUIRootComponent, instead we have one subcomponent that
- * creates a new ViewInstanceCreator any time we need to inflate a view.
- */
- @Subcomponent(modules = ViewAttributeProvider.class)
public interface ViewInstanceCreator {
+
+ /** Factory for creating a ViewInstanceCreator. */
+ @Subcomponent.Factory
+ interface Factory {
+ ViewInstanceCreator build(
+ @BindsInstance @Named(VIEW_CONTEXT) Context context,
+ @BindsInstance AttributeSet attributeSet);
+ }
+
/**
* Creates the QuickStatusBarHeader.
*/
@@ -152,36 +134,6 @@ public class InjectionInflationController {
QSCustomizer createQSCustomizer();
}
- /**
- * Module for providing view-specific constructor objects.
- */
- @Module
- public class ViewAttributeProvider {
- private final Context mContext;
- private final AttributeSet mAttrs;
-
- private ViewAttributeProvider(Context context, AttributeSet attrs) {
- mContext = context;
- mAttrs = attrs;
- }
-
- /**
- * Provides the view-themed context (as opposed to the global sysui application context).
- */
- @Provides
- @Named(VIEW_CONTEXT)
- public Context provideContext() {
- return mContext;
- }
-
- /**
- * Provides the AttributeSet for the current view being inflated.
- */
- @Provides
- public AttributeSet provideAttributeSet() {
- return mAttrs;
- }
- }
private class InjectionFactory implements LayoutInflater.Factory2 {
@@ -189,10 +141,9 @@ public class InjectionInflationController {
public View onCreateView(String name, Context context, AttributeSet attrs) {
Method creationMethod = mInjectionMap.get(name);
if (creationMethod != null) {
- ViewAttributeProvider provider = new ViewAttributeProvider(context, attrs);
try {
return (View) creationMethod.invoke(
- mViewCreator.createInstanceCreator(provider));
+ mViewInstanceCreatorFactory.build(context, attrs));
} catch (IllegalAccessException e) {
throw new InflateException("Could not inflate " + name, e);
} catch (InvocationTargetException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index e5f30cf63ac3..72f1f22c0ba1 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -21,12 +21,15 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.provider.Settings;
+import android.text.TextUtils;
import android.view.View;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.function.Consumer;
public class Utils {
@@ -143,4 +146,21 @@ public class Utils {
Settings.Secure.MEDIA_CONTROLS_RESUME, 1);
return useQsMediaPlayer(context) && flag > 0;
}
+
+ /**
+ * Get the set of apps for which the user has manually disabled resumption.
+ */
+ public static Set<String> getBlockedMediaApps(Context context) {
+ String list = Settings.Secure.getString(context.getContentResolver(),
+ Settings.Secure.MEDIA_CONTROLS_RESUME_BLOCKED);
+ if (TextUtils.isEmpty(list)) {
+ return new HashSet<>();
+ }
+ String[] names = list.split(":");
+ Set<String> apps = new HashSet<>(names.length);
+ for (String s : names) {
+ apps.add(s);
+ }
+ return apps;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt
new file mode 100644
index 000000000000..92c73a412577
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.kotlin
+
+/**
+ * If [value] is not null, then returns block(value). Otherwise returns null.
+ */
+inline fun <T : Any, R> transform(value: T?, block: (T) -> R): R? = value?.let(block)
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
index 42393375b45e..e8c5db74f494 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
@@ -18,7 +18,7 @@ package com.android.systemui.volume;
import android.content.res.Configuration;
-import com.android.systemui.DemoMode;
+import com.android.systemui.demomode.DemoMode;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index 1c2a2fa53bea..428751bbd73c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -27,6 +27,8 @@ import android.view.WindowManager.LayoutParams;
import com.android.settingslib.applications.InterestingConfigChanges;
import com.android.systemui.Dependency;
+import com.android.systemui.demomode.DemoMode;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.PluginDependencyProvider;
@@ -38,6 +40,8 @@ import com.android.systemui.tuner.TunerService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -72,8 +76,11 @@ public class VolumeDialogComponent implements VolumeComponent, TunerService.Tuna
);
@Inject
- public VolumeDialogComponent(Context context, KeyguardViewMediator keyguardViewMediator,
- VolumeDialogControllerImpl volumeDialogController) {
+ public VolumeDialogComponent(
+ Context context,
+ KeyguardViewMediator keyguardViewMediator,
+ VolumeDialogControllerImpl volumeDialogController,
+ DemoModeController demoModeController) {
mContext = context;
mKeyguardViewMediator = keyguardViewMediator;
mController = volumeDialogController;
@@ -94,6 +101,7 @@ public class VolumeDialogComponent implements VolumeComponent, TunerService.Tuna
applyConfiguration();
Dependency.get(TunerService.class).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
VOLUME_SILENT_DO_NOT_DISTURB);
+ demoModeController.addCallback(this);
}
protected VolumeDialog createDefault() {
@@ -164,6 +172,13 @@ public class VolumeDialogComponent implements VolumeComponent, TunerService.Tuna
}
@Override
+ public List<String> demoCommands() {
+ List<String> s = new ArrayList<>();
+ s.add(DemoMode.COMMAND_VOLUME);
+ return s;
+ }
+
+ @Override
public void register() {
mController.register();
DndTile.setCombinedIcon(mContext, true);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 4b119dd7e176..51ad30ebcac6 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -940,6 +940,7 @@ public class VolumeDialogImpl implements VolumeDialog,
protected void onStateChangedH(State state) {
if (D.BUG) Log.d(TAG, "onStateChangedH() state: " + state.toString());
if (mState != null && state != null
+ && mState.ringerModeInternal != -1
&& mState.ringerModeInternal != state.ringerModeInternal
&& state.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE) {
mController.vibrate(VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK));
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 4c0762e4ea32..0d52e4fefd3e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -79,7 +79,9 @@ public class KeyguardClockSwitchTest extends SysuiTestCase {
.thenReturn(mMockKeyguardSliceView);
InjectionInflationController inflationController = new InjectionInflationController(
- SystemUIFactory.getInstance().getRootComponent());
+ SystemUIFactory.getInstance()
+ .getRootComponent()
+ .createViewInstanceCreatorFactory());
LayoutInflater layoutInflater = inflationController
.injectable(LayoutInflater.from(getContext()));
layoutInflater.setPrivateFactory(new LayoutInflater.Factory2() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
index e6c2ddcf7e65..aa4db3205d82 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
@@ -65,7 +65,9 @@ public class KeyguardPresentationTest extends SysuiTestCase {
allowTestableLooperAsMainThread();
InjectionInflationController inflationController = new InjectionInflationController(
- SystemUIFactory.getInstance().getRootComponent());
+ SystemUIFactory.getInstance()
+ .getRootComponent()
+ .createViewInstanceCreatorFactory());
mLayoutInflater = inflationController.injectable(LayoutInflater.from(mContext));
mLayoutInflater.setPrivateFactory(new LayoutInflater.Factory2() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
index bc3c3d995ce6..560d581c20e7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
@@ -51,7 +51,9 @@ public class KeyguardStatusViewTest extends SysuiTestCase {
allowTestableLooperAsMainThread();
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
InjectionInflationController inflationController = new InjectionInflationController(
- SystemUIFactory.getInstance().getRootComponent());
+ SystemUIFactory.getInstance()
+ .getRootComponent()
+ .createViewInstanceCreatorFactory());
LayoutInflater layoutInflater = inflationController
.injectable(LayoutInflater.from(getContext()));
mKeyguardStatusView =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 60f0cd9da5f2..e967a5d607eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -82,8 +82,7 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
allowTestableLooperAsMainThread();
MockitoAnnotations.initMocks(this);
- mFsc = new ForegroundServiceController(
- mEntryManager, mAppOpsController, mMainHandler);
+ mFsc = new ForegroundServiceController(mAppOpsController, mMainHandler);
mListener = new ForegroundServiceNotificationListener(
mContext, mFsc, mEntryManager, mNotifPipeline,
mock(ForegroundServiceLifetimeExtender.class), mClock);
@@ -115,85 +114,6 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
}
@Test
- public void testAppOps_appOpChangedBeforeNotificationExists() {
- // GIVEN app op exists, but notification doesn't exist in NEM yet
- NotificationEntry entry = createFgEntry();
- mFsc.onAppOpChanged(
- AppOpsManager.OP_CAMERA,
- entry.getSbn().getUid(),
- entry.getSbn().getPackageName(),
- true);
- assertFalse(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
-
- // WHEN the notification is added
- mEntryListener.onPendingEntryAdded(entry);
-
- // THEN the app op is added to the entry
- Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
- }
-
- @Test
- public void testAppOps_appOpAddedToForegroundNotif() {
- // GIVEN a notification associated with a foreground service
- NotificationEntry entry = addFgEntry();
- when(mEntryManager.getPendingOrActiveNotif(entry.getKey())).thenReturn(entry);
-
- // WHEN we are notified of a new app op for this notification
- mFsc.onAppOpChanged(
- AppOpsManager.OP_CAMERA,
- entry.getSbn().getUid(),
- entry.getSbn().getPackageName(),
- true);
-
- // THEN the app op is added to the entry
- Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
-
- // THEN notification views are updated since the notification is visible
- verify(mEntryManager, times(1)).updateNotifications(anyString());
- }
-
- @Test
- public void testAppOpsAlreadyAdded() {
- // GIVEN a foreground service associated notification that already has the correct app op
- NotificationEntry entry = addFgEntry();
- entry.mActiveAppOps.add(AppOpsManager.OP_CAMERA);
- when(mEntryManager.getPendingOrActiveNotif(entry.getKey())).thenReturn(entry);
-
- // WHEN we are notified of the same app op for this notification
- mFsc.onAppOpChanged(
- AppOpsManager.OP_CAMERA,
- entry.getSbn().getUid(),
- entry.getSbn().getPackageName(),
- true);
-
- // THEN the app op still exists in the notification entry
- Assert.assertTrue(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
-
- // THEN notification views aren't updated since nothing changed
- verify(mEntryManager, never()).updateNotifications(anyString());
- }
-
- @Test
- public void testAppOps_appOpNotAddedToUnrelatedNotif() {
- // GIVEN no notification entries correspond to the newly updated appOp
- NotificationEntry entry = addFgEntry();
- when(mEntryManager.getPendingOrActiveNotif(entry.getKey())).thenReturn(null);
-
- // WHEN a new app op is detected
- mFsc.onAppOpChanged(
- AppOpsManager.OP_CAMERA,
- entry.getSbn().getUid(),
- entry.getSbn().getPackageName(),
- true);
-
- // THEN we won't see appOps on the entry
- Assert.assertFalse(entry.mActiveAppOps.contains(AppOpsManager.OP_CAMERA));
-
- // THEN notification views aren't updated since nothing changed
- verify(mEntryManager, never()).updateNotifications(anyString());
- }
-
- @Test
public void testAppOpsCRUD() {
// no crash on remove that doesn't exist
mFsc.onAppOpChanged(9, 1000, "pkg1", false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
index afcd4414c667..7567f0cf04b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/assist/AssistHandleBehaviorControllerTest.java
@@ -41,7 +41,7 @@ import com.android.internal.app.AssistUtils;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController;
import org.junit.After;
import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 1538a32ecf8a..5c86fcb6b008 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -211,7 +211,8 @@ public class BubbleControllerTest extends SysuiTestCase {
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
mSuperStatusBarViewFactory = new SuperStatusBarViewFactory(mContext,
- new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()),
+ new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()
+ .createViewInstanceCreatorFactory()),
new NotificationShelfComponent.Builder() {
@Override
public NotificationShelfComponent.Builder notificationShelf(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
index 0e7cb79ec266..196aa65bd28f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
@@ -201,7 +201,8 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
mSuperStatusBarViewFactory = new SuperStatusBarViewFactory(mContext,
- new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()),
+ new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()
+ .createViewInstanceCreatorFactory()),
new NotificationShelfComponent.Builder() {
@Override
public NotificationShelfComponent.Builder notificationShelf(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index f70fb4f55a8d..d1f505baa9e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -254,16 +254,12 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
int mCleanDateFormatInvokations;
private int mCounter;
- Uri getUri() {
- return mSliceUri;
- }
+ TestableKeyguardSliceProvider() {
+ super();
- @Override
- protected void inject() {
mAlarmManager = KeyguardSliceProviderTest.this.mAlarmManager;
mContentResolver = KeyguardSliceProviderTest.this.mContentResolver;
mZenModeController = KeyguardSliceProviderTest.this.mZenModeController;
- mMediaWakeLock = KeyguardSliceProviderTest.this.mMediaWakeLock;
mDozeParameters = KeyguardSliceProviderTest.this.mDozeParameters;
mNextAlarmController = KeyguardSliceProviderTest.this.mNextAlarmController;
mStatusBarStateController = KeyguardSliceProviderTest.this.mStatusBarStateController;
@@ -272,6 +268,17 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
}
@Override
+ public boolean onCreateSliceProvider() {
+ boolean result = super.onCreateSliceProvider();
+ mMediaWakeLock = KeyguardSliceProviderTest.this.mMediaWakeLock;
+ return result;
+ }
+
+ Uri getUri() {
+ return mSliceUri;
+ }
+
+ @Override
protected boolean isDndOn() {
return mIsZenMode;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 90e9ef4e9c56..c874b1fb72ad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -42,10 +42,11 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.dump.DumpManager;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.DeviceConfigProxyFake;
+import com.android.systemui.util.InjectionInflationController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -71,6 +72,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock PowerManager mPowerManager;
private @Mock TrustManager mTrustManager;
private @Mock NavigationModeController mNavigationModeController;
+ private @Mock InjectionInflationController mInjectionInflationController;
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -88,7 +90,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mContext, mFalsingManager, mLockPatternUtils, mBroadcastDispatcher,
() -> mStatusBarKeyguardViewManager,
mDismissCallbackRegistry, mUpdateMonitor, mDumpManager, mUiBgExecutor,
- mPowerManager, mTrustManager, mDeviceConfig, mNavigationModeController);
+ mPowerManager, mTrustManager, mDeviceConfig, mNavigationModeController,
+ mInjectionInflationController);
mViewMediator.start();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
index 492b33e3c4a6..2e794a40d238 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataCombineLatestTest.java
@@ -83,8 +83,8 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
mManager.addListener(mListener);
mMediaData = new MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null,
- new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null, true, null, false,
- KEY, false);
+ new ArrayList<>(), new ArrayList<>(), PACKAGE, null, null, null, true, null, true,
+ false, KEY, false);
mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index a4ebe1ff2a4e..457d559449e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -199,6 +199,58 @@ class MediaDataManagerTest : SysuiTestCase() {
}
@Test
+ fun testAppBlockedFromResumption() {
+ // GIVEN that the manager has a notification with a resume action
+ val listener = TestListener()
+ mediaDataManager.addListener(listener)
+ whenever(controller.metadata).thenReturn(metadataBuilder.build())
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+ val data = listener.data!!
+ assertThat(data.resumption).isFalse()
+ mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
+
+ // and the manager should block the package from creating resume controls
+ val blocked = mutableSetOf(PACKAGE_NAME, "com.example.app")
+ mediaDataManager.appsBlockedFromResume = blocked
+
+ // WHEN the notification is removed
+ mediaDataManager.onNotificationRemoved(KEY)
+
+ // THEN the media data is removed
+ assertThat(listener.removedKey!!).isEqualTo(KEY)
+ }
+
+ @Test
+ fun testAppUnblockedFromResumption() {
+ // GIVEN that an app was blocked from resuming
+ val blocked = mutableSetOf(PACKAGE_NAME, "com.example.app")
+ mediaDataManager.appsBlockedFromResume = blocked
+
+ // and GIVEN that the manager has a notification from that app with a resume action
+ val listener = TestListener()
+ mediaDataManager.addListener(listener)
+ whenever(controller.metadata).thenReturn(metadataBuilder.build())
+ mediaDataManager.onNotificationAdded(KEY, mediaNotification)
+ assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
+ assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
+ val data = listener.data!!
+ assertThat(data.resumption).isFalse()
+ mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
+
+ // WHEN the app is unblocked
+ mediaDataManager.appsBlockedFromResume = mutableSetOf("com.example.app")
+
+ // and the notification is removed
+ mediaDataManager.onNotificationRemoved(KEY)
+
+ // THEN the entry will stay as a resume control
+ assertThat(listener.key!!).isEqualTo(PACKAGE_NAME)
+ assertThat(listener.oldKey!!).isEqualTo(KEY)
+ }
+
+ @Test
fun testAddResumptionControls() {
val listener = TestListener()
mediaDataManager.addListener(listener)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
new file mode 100644
index 000000000000..118cffc2d5b8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+public class MediaPlayerDataTest : SysuiTestCase() {
+
+ companion object {
+ val LOCAL = true
+ val RESUMPTION = true
+ }
+
+ @Before
+ fun setup() {
+ MediaPlayerData.clear()
+ }
+
+ @Test
+ fun addPlayingThenRemote() {
+ val playerIsPlaying = mock(MediaControlPanel::class.java)
+ whenever(playerIsPlaying.isPlaying).thenReturn(true)
+ val dataIsPlaying = createMediaData(LOCAL, !RESUMPTION)
+
+ val playerIsRemote = mock(MediaControlPanel::class.java)
+ whenever(playerIsRemote.isPlaying).thenReturn(false)
+ val dataIsRemote = createMediaData(!LOCAL, !RESUMPTION)
+
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying)
+ MediaPlayerData.addMediaPlayer("2", dataIsRemote, playerIsRemote)
+
+ val players = MediaPlayerData.players()
+ assertThat(players).hasSize(2)
+ assertThat(players).containsExactly(playerIsPlaying, playerIsRemote).inOrder()
+ }
+
+ @Test
+ fun switchPlayersPlaying() {
+ val playerIsPlaying1 = mock(MediaControlPanel::class.java)
+ whenever(playerIsPlaying1.isPlaying).thenReturn(true)
+ val dataIsPlaying1 = createMediaData(LOCAL, !RESUMPTION)
+
+ val playerIsPlaying2 = mock(MediaControlPanel::class.java)
+ whenever(playerIsPlaying2.isPlaying).thenReturn(false)
+ val dataIsPlaying2 = createMediaData(LOCAL, !RESUMPTION)
+
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1)
+ MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2)
+
+ whenever(playerIsPlaying1.isPlaying).thenReturn(false)
+ whenever(playerIsPlaying2.isPlaying).thenReturn(true)
+
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1)
+ MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2)
+
+ val players = MediaPlayerData.players()
+ assertThat(players).hasSize(2)
+ assertThat(players).containsExactly(playerIsPlaying2, playerIsPlaying1).inOrder()
+ }
+
+ @Test
+ fun fullOrderTest() {
+ val playerIsPlaying = mock(MediaControlPanel::class.java)
+ whenever(playerIsPlaying.isPlaying).thenReturn(true)
+ val dataIsPlaying = createMediaData(LOCAL, !RESUMPTION)
+
+ val playerIsPlayingAndRemote = mock(MediaControlPanel::class.java)
+ whenever(playerIsPlayingAndRemote.isPlaying).thenReturn(true)
+ val dataIsPlayingAndRemote = createMediaData(!LOCAL, !RESUMPTION)
+
+ val playerIsStoppedAndLocal = mock(MediaControlPanel::class.java)
+ whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false)
+ val dataIsStoppedAndLocal = createMediaData(LOCAL, !RESUMPTION)
+
+ val playerIsStoppedAndRemote = mock(MediaControlPanel::class.java)
+ whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false)
+ val dataIsStoppedAndRemote = createMediaData(!LOCAL, !RESUMPTION)
+
+ val playerCanResume = mock(MediaControlPanel::class.java)
+ whenever(playerCanResume.isPlaying).thenReturn(false)
+ val dataCanResume = createMediaData(LOCAL, RESUMPTION)
+
+ MediaPlayerData.addMediaPlayer("3", dataIsStoppedAndLocal, playerIsStoppedAndLocal)
+ MediaPlayerData.addMediaPlayer("5", dataIsStoppedAndRemote, playerIsStoppedAndRemote)
+ MediaPlayerData.addMediaPlayer("4", dataCanResume, playerCanResume)
+ MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying)
+ MediaPlayerData.addMediaPlayer("2", dataIsPlayingAndRemote, playerIsPlayingAndRemote)
+
+ val players = MediaPlayerData.players()
+ assertThat(players).hasSize(5)
+ assertThat(players).containsExactly(playerIsPlaying, playerIsPlayingAndRemote,
+ playerIsStoppedAndLocal, playerCanResume, playerIsStoppedAndRemote).inOrder()
+ }
+
+ private fun createMediaData(isLocalSession: Boolean, resumption: Boolean) =
+ MediaData(0, false, 0, null, null, null, null, null, emptyList(), emptyList<Int>(), "",
+ null, null, null, true, null, isLocalSession, resumption, null, false)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarButtonTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java
index aae075777506..37b7cbeb8ad6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarButtonTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -35,6 +35,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestableContext;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -65,6 +66,7 @@ public class NavigationBarButtonTest extends SysuiTestCase {
mDependency.injectMockDependency(AssistManager.class);
mDependency.injectMockDependency(OverviewProxyService.class);
mDependency.injectMockDependency(KeyguardStateController.class);
+ mDependency.injectMockDependency(NavigationBarController.class);
mNavBar = new NavigationBarView(context, null);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
index 3c66ac6acd04..2e4d8a7ff472 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NavigationBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar;
+package com.android.systemui.navigationbar;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -36,12 +36,32 @@ import static org.mockito.Mockito.verify;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.util.SparseArray;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
import androidx.test.filters.SmallTest;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.phone.NavigationBarFragment;
+import com.android.systemui.accessibility.SystemActions;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+
+import java.util.Optional;
import org.junit.After;
import org.junit.Before;
@@ -55,27 +75,47 @@ import org.junit.runner.RunWith;
public class NavigationBarControllerTest extends SysuiTestCase {
private NavigationBarController mNavigationBarController;
- private NavigationBarFragment mDefaultNavBar;
- private NavigationBarFragment mSecondaryNavBar;
+ private NavigationBar mDefaultNavBar;
+ private NavigationBar mSecondaryNavBar;
private static final int SECONDARY_DISPLAY = 1;
@Before
public void setUp() {
mNavigationBarController = spy(
- new NavigationBarController(mContext, Dependency.get(Dependency.MAIN_HANDLER),
- mock(CommandQueue.class)));
+ new NavigationBarController(mContext,
+ mock(WindowManager.class),
+ () -> mock(AssistManager.class),
+ mock(AccessibilityManager.class),
+ mock(AccessibilityManagerWrapper.class),
+ mock(DeviceProvisionedController.class),
+ mock(MetricsLogger.class),
+ mock(OverviewProxyService.class),
+ mock(NavigationModeController.class),
+ mock(StatusBarStateController.class),
+ mock(SysUiState.class),
+ mock(BroadcastDispatcher.class),
+ mock(CommandQueue.class),
+ mock(Divider.class),
+ Optional.of(mock(Recents.class)),
+ () -> mock(StatusBar.class),
+ mock(ShadeController.class),
+ mock(NotificationRemoteInputManager.class),
+ mock(SystemActions.class),
+ Dependency.get(Dependency.MAIN_HANDLER),
+ mock(UiEventLogger.class),
+ mock(ConfigurationController.class)));
initializeNavigationBars();
}
private void initializeNavigationBars() {
mNavigationBarController.mNavigationBars = mock(SparseArray.class);
- mDefaultNavBar = mock(NavigationBarFragment.class);
+ mDefaultNavBar = mock(NavigationBar.class);
mDefaultNavBar.mDisplayId = DEFAULT_DISPLAY;
doReturn(mDefaultNavBar)
.when(mNavigationBarController.mNavigationBars).get(DEFAULT_DISPLAY);
- mSecondaryNavBar = mock(NavigationBarFragment.class);
+ mSecondaryNavBar = mock(NavigationBar.class);
mSecondaryNavBar.mDisplayId = SECONDARY_DISPLAY;
doReturn(mSecondaryNavBar)
.when(mNavigationBarController.mNavigationBars).get(SECONDARY_DISPLAY);
@@ -90,22 +130,22 @@ public class NavigationBarControllerTest extends SysuiTestCase {
@Test
public void testCreateNavigationBarsIncludeDefaultTrue() {
- doNothing().when(mNavigationBarController).createNavigationBar(any(), any());
+ doNothing().when(mNavigationBarController).createNavigationBar(any(), any(), any());
mNavigationBarController.createNavigationBars(true, null);
verify(mNavigationBarController).createNavigationBar(
- argThat(display -> display.getDisplayId() == DEFAULT_DISPLAY), any());
+ argThat(display -> display.getDisplayId() == DEFAULT_DISPLAY), any(), any());
}
@Test
public void testCreateNavigationBarsIncludeDefaultFalse() {
- doNothing().when(mNavigationBarController).createNavigationBar(any(), any());
+ doNothing().when(mNavigationBarController).createNavigationBar(any(), any(), any());
mNavigationBarController.createNavigationBars(false, null);
verify(mNavigationBarController, never()).createNavigationBar(
- argThat(display -> display.getDisplayId() == DEFAULT_DISPLAY), any());
+ argThat(display -> display.getDisplayId() == DEFAULT_DISPLAY), any(), any());
}
// Tests if NPE occurs when call checkNavBarModes() with invalid display.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarInflaterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java
index 80e33fbc6acb..7369c82e23ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarInflaterViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doNothing;
@@ -32,6 +32,9 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.NavigationBarInflaterView;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.recents.OverviewProxyService;
import org.junit.After;
@@ -54,6 +57,7 @@ public class NavigationBarInflaterViewTest extends SysuiTestCase {
mDependency.injectMockDependency(AssistManager.class);
mDependency.injectMockDependency(OverviewProxyService.class);
mDependency.injectMockDependency(NavigationModeController.class);
+ mDependency.injectMockDependency(NavigationBarController.class);
mNavBarInflaterView = spy(new NavigationBarInflaterView(mContext, null));
doNothing().when(mNavBarInflaterView).createInflaters();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarRotationContextTest.java
index f66524114292..51cf5016e8cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarRotationContextTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -30,7 +30,9 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestableContext;
-import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
+import com.android.systemui.navigationbar.RotationButton;
+import com.android.systemui.navigationbar.RotationButtonController;
import com.android.systemui.statusbar.policy.RotationLockController;
import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index 00cbddc87726..a643c2dc0f19 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -1,18 +1,20 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
@@ -21,7 +23,7 @@ import static android.inputmethodservice.InputMethodService.IME_VISIBLE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
-import static com.android.systemui.statusbar.phone.NavigationBarFragment.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
+import static com.android.systemui.navigationbar.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -29,42 +31,35 @@ import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
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;
-import android.annotation.LayoutRes;
-import android.annotation.Nullable;
-import android.app.Fragment;
-import android.app.FragmentController;
-import android.app.FragmentHostCallback;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.hardware.display.DisplayManagerGlobal;
-import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
-import android.testing.LeakCheck.Tracker;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.Display;
import android.view.DisplayInfo;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
import android.view.WindowManager;
-import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
+import android.view.WindowMetrics;
+import android.view.accessibility.AccessibilityManager;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.Dependency;
-import com.android.systemui.SysuiBaseFragmentTest;
+import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestableContext;
import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.assist.AssistManager;
@@ -76,10 +71,15 @@ import com.android.systemui.recents.Recents;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.utils.leaks.LeakCheckedTest;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -90,94 +90,62 @@ import java.util.Optional;
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
-public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
+public class NavigationBarTest extends SysuiTestCase {
private static final int EXTERNAL_DISPLAY_ID = 2;
- private static final int NAV_BAR_VIEW_ID = 43;
- private Fragment mFragmentExternalDisplay;
- private FragmentController mControllerExternalDisplay;
+ private NavigationBar mNavigationBar;
+ private NavigationBar mExternalDisplayNavigationBar;
private SysuiTestableContext mSysuiTestableContextExternal;
private OverviewProxyService mOverviewProxyService;
private CommandQueue mCommandQueue;
private SysUiState mMockSysUiState;
+ private Handler mHandler;
@Mock
private BroadcastDispatcher mBroadcastDispatcher;
@Mock
- private Divider mDivider;
- @Mock
- private Recents mRecents;
- @Mock
- private SystemActions mSystemActions;
- @Mock
private UiEventLogger mUiEventLogger;
+ @Rule
+ public final LeakCheckedTest.SysuiLeakCheck mLeakCheck = new LeakCheckedTest.SysuiLeakCheck();
private AccessibilityManagerWrapper mAccessibilityWrapper =
- new AccessibilityManagerWrapper(mContext) {
- Tracker mTracker = mLeakCheck.getTracker("accessibility_manager");
-
- @Override
- public void addCallback(AccessibilityServicesStateChangeListener listener) {
- mTracker.getLeakInfo(listener).addAllocation(new Throwable());
- }
-
- @Override
- public void removeCallback(AccessibilityServicesStateChangeListener listener) {
- mTracker.getLeakInfo(listener).clearAllocations();
- }
- };
-
- public NavigationBarFragmentTest() {
- super(NavigationBarFragment.class);
- }
-
- protected void createRootView() {
- mView = new NavigationBarFrame(mSysuiContext);
- mView.setId(NAV_BAR_VIEW_ID);
- }
+ new AccessibilityManagerWrapper(mContext);
@Before
- public void setupFragment() throws Exception {
+ public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
mCommandQueue = new CommandQueue(mContext);
setupSysuiDependency();
- createRootView();
- mOverviewProxyService =
- mDependency.injectMockDependency(OverviewProxyService.class);
+ mDependency.injectMockDependency(AssistManager.class);
+ mDependency.injectMockDependency(KeyguardStateController.class);
+ mDependency.injectMockDependency(StatusBarStateController.class);
+ mDependency.injectMockDependency(NavigationBarController.class);
+ mDependency.injectMockDependency(Divider.class);
+ mOverviewProxyService = mDependency.injectMockDependency(OverviewProxyService.class);
TestableLooper.get(this).runWithLooper(() -> {
mHandler = new Handler();
-
- mFragment = instantiate(mSysuiContext, NavigationBarFragment.class.getName(), null);
- mFragments = FragmentController.createController(
- new HostCallbacksForExternalDisplay(mSysuiContext));
- mFragments.attachHost(null);
- mFragments.getFragmentManager().beginTransaction()
- .replace(NAV_BAR_VIEW_ID, mFragment)
- .commit();
- mControllerExternalDisplay = FragmentController.createController(
- new HostCallbacksForExternalDisplay(mSysuiTestableContextExternal));
- mControllerExternalDisplay.attachHost(null);
- mFragmentExternalDisplay = instantiate(mSysuiTestableContextExternal,
- NavigationBarFragment.class.getName(), null);
- mControllerExternalDisplay.getFragmentManager().beginTransaction()
- .replace(NAV_BAR_VIEW_ID, mFragmentExternalDisplay)
- .commit();
+ mNavigationBar = createNavBar(mContext);
+ mExternalDisplayNavigationBar = createNavBar(mSysuiTestableContextExternal);
});
}
private void setupSysuiDependency() {
Display display = new Display(DisplayManagerGlobal.getInstance(), EXTERNAL_DISPLAY_ID,
new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
- mSysuiTestableContextExternal = (SysuiTestableContext) mSysuiContext.createDisplayContext(
+ mSysuiTestableContextExternal = (SysuiTestableContext) getContext().createDisplayContext(
display);
- injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
WindowManager windowManager = mock(WindowManager.class);
Display defaultDisplay = mContext.getSystemService(WindowManager.class).getDefaultDisplay();
when(windowManager.getDefaultDisplay()).thenReturn(
defaultDisplay);
+ WindowMetrics metrics = mContext.getSystemService(WindowManager.class)
+ .getMaximumWindowMetrics();
+ when(windowManager.getMaximumWindowMetrics()).thenReturn(metrics);
+ doNothing().when(windowManager).addView(any(), any());
mContext.addMockSystemService(Context.WINDOW_SERVICE, windowManager);
+ mSysuiTestableContextExternal.addMockSystemService(Context.WINDOW_SERVICE, windowManager);
mDependency.injectTestDependency(Dependency.BG_LOOPER, Looper.getMainLooper());
mDependency.injectTestDependency(AccessibilityManagerWrapper.class, mAccessibilityWrapper);
@@ -188,20 +156,15 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
@Test
public void testHomeLongPress() {
- NavigationBarFragment navigationBarFragment = (NavigationBarFragment) mFragment;
-
- mFragments.dispatchResume();
- processAllMessages();
- navigationBarFragment.onHomeLongClick(navigationBarFragment.getView());
+ mNavigationBar.onViewAttachedToWindow(mNavigationBar.createView(null));
+ mNavigationBar.onHomeLongClick(mNavigationBar.getView());
verify(mUiEventLogger, times(1)).log(NAVBAR_ASSIST_LONGPRESS);
}
@Test
public void testRegisteredWithDispatcher() {
- mFragments.dispatchResume();
- processAllMessages();
-
+ mNavigationBar.onViewAttachedToWindow(mNavigationBar.createView(null));
verify(mBroadcastDispatcher).registerReceiverWithHandler(
any(BroadcastReceiver.class),
any(IntentFilter.class),
@@ -212,16 +175,12 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
@Test
public void testSetImeWindowStatusWhenImeSwitchOnDisplay() {
// Create default & external NavBar fragment.
- NavigationBarFragment defaultNavBar = (NavigationBarFragment) mFragment;
- NavigationBarFragment externalNavBar = (NavigationBarFragment) mFragmentExternalDisplay;
- mFragments.dispatchCreate();
- processAllMessages();
- mFragments.dispatchResume();
- processAllMessages();
- mControllerExternalDisplay.dispatchCreate();
- processAllMessages();
- mControllerExternalDisplay.dispatchResume();
- processAllMessages();
+ NavigationBar defaultNavBar = mNavigationBar;
+ NavigationBar externalNavBar = mExternalDisplayNavigationBar;
+ doNothing().when(defaultNavBar).checkNavBarModes();
+ doNothing().when(externalNavBar).checkNavBarModes();
+ defaultNavBar.createView(null);
+ externalNavBar.createView(null);
// Set IME window status for default NavBar.
mCommandQueue.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
@@ -246,91 +205,36 @@ public class NavigationBarFragmentTest extends SysuiBaseFragmentTest {
assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
}
- @Override
- protected Fragment instantiate(Context context, String className, Bundle arguments) {
+ private NavigationBar createNavBar(Context context) {
DeviceProvisionedController deviceProvisionedController =
mock(DeviceProvisionedController.class);
when(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
assertNotNull(mAccessibilityWrapper);
- return new NavigationBarFragment(
+ return spy(new NavigationBar(context,
+ mock(WindowManager.class),
+ () -> mock(AssistManager.class),
+ mock(AccessibilityManager.class),
context.getDisplayId() == DEFAULT_DISPLAY ? mAccessibilityWrapper
: mock(AccessibilityManagerWrapper.class),
deviceProvisionedController,
new MetricsLogger(),
- mock(AssistManager.class),
mOverviewProxyService,
mock(NavigationModeController.class),
mock(StatusBarStateController.class),
mMockSysUiState,
mBroadcastDispatcher,
mCommandQueue,
- mDivider,
- Optional.of(mRecents),
+ mock(Divider.class),
+ Optional.of(mock(Recents.class)),
() -> mock(StatusBar.class),
mock(ShadeController.class),
mock(NotificationRemoteInputManager.class),
mock(SystemActions.class),
mHandler,
- mUiEventLogger);
+ mUiEventLogger));
}
- private class HostCallbacksForExternalDisplay extends
- FragmentHostCallback<NavigationBarFragmentTest> {
- private Context mDisplayContext;
-
- HostCallbacksForExternalDisplay(Context context) {
- super(context, mHandler, 0);
- mDisplayContext = context;
- }
-
- @Override
- public NavigationBarFragmentTest onGetHost() {
- return NavigationBarFragmentTest.this;
- }
-
- @Override
- public Fragment instantiate(Context context, String className, Bundle arguments) {
- return NavigationBarFragmentTest.this.instantiate(context, className, arguments);
- }
-
- @Override
- public View onFindViewById(int id) {
- return mView.findViewById(id);
- }
-
- @Override
- public LayoutInflater onGetLayoutInflater() {
- return new LayoutInflaterWrapper(mDisplayContext);
- }
- }
-
- private static class LayoutInflaterWrapper extends LayoutInflater {
- protected LayoutInflaterWrapper(Context context) {
- super(context);
- }
-
- @Override
- public LayoutInflater cloneInContext(Context newContext) {
- return null;
- }
-
- @Override
- public View inflate(@LayoutRes int resource, @Nullable ViewGroup root,
- boolean attachToRoot) {
- NavigationBarView view = mock(NavigationBarView.class);
- when(view.getDisplay()).thenReturn(mContext.getDisplay());
- when(view.getBackButton()).thenReturn(mock(ButtonDispatcher.class));
- when(view.getHomeButton()).thenReturn(mock(ButtonDispatcher.class));
- when(view.getRecentsButton()).thenReturn(mock(ButtonDispatcher.class));
- when(view.getAccessibilityButton()).thenReturn(mock(ButtonDispatcher.class));
- when(view.getRotateSuggestionButton()).thenReturn(mock(RotationContextButton.class));
- when(view.getBarTransitions()).thenReturn(mock(NavigationBarTransitions.class));
- when(view.getLightTransitionsController()).thenReturn(
- mock(LightBarTransitionsController.class));
- when(view.getRotationButtonController()).thenReturn(
- mock(RotationButtonController.class));
- when(view.isRecentsButtonVisible()).thenReturn(true);
- return view;
- }
+ private void processAllMessages() {
+ TestableLooper.get(this).processAllMessages();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
index 14c6e9f9624d..7e0920cc998d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarTransitionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
@@ -1,18 +1,20 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -30,9 +32,13 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.NavigationBarTransitions;
+import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
@@ -53,6 +59,7 @@ public class NavigationBarTransitionsTest extends SysuiTestCase {
mDependency.injectMockDependency(OverviewProxyService.class);
mDependency.injectMockDependency(StatusBarStateController.class);
mDependency.injectMockDependency(KeyguardStateController.class);
+ mDependency.injectMockDependency(NavigationBarController.class);
doReturn(mContext)
.when(mDependency.injectMockDependency(NavigationModeController.class))
.getCurrentUserContext();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyButtonViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java
index d52d6860bf42..3f10c8da576b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyButtonViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java
@@ -1,18 +1,20 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.policy;
+package com.android.systemui.navigationbar.buttons;
import static android.view.KeyEvent.ACTION_DOWN;
import static android.view.KeyEvent.ACTION_UP;
@@ -23,12 +25,12 @@ import static android.view.KeyEvent.KEYCODE_APP_SWITCH;
import static android.view.KeyEvent.KEYCODE_BACK;
import static android.view.KeyEvent.KEYCODE_HOME;
-import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_LONGPRESS;
-import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_TAP;
-import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_LONGPRESS;
-import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_TAP;
-import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS;
-import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_TAP;
+import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_TAP;
+import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_TAP;
+import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_TAP;
import static junit.framework.Assert.assertEquals;
@@ -52,6 +54,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.navigationbar.buttons.KeyButtonView;
import com.android.systemui.recents.OverviewProxyService;
import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java
index 1fb28f0878bd..d56aa777706b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarContextTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.buttons;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -35,7 +35,9 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
-import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import com.android.systemui.navigationbar.buttons.ContextualButton;
+import com.android.systemui.navigationbar.buttons.ContextualButtonGroup;
+import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
import org.junit.Before;
import org.junit.Ignore;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java
index a04bcc0b29c5..0320103ceaa8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NearestTouchFrameTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java
@@ -1,18 +1,20 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
+ * 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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.systemui.navigationbar.buttons;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -31,6 +33,7 @@ import android.view.View;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.navigationbar.buttons.NearestTouchFrame;
import org.junit.Before;
import org.junit.Test;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
index f4c07004f632..95a230f6511c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedGestureHandlerTest.java
@@ -31,7 +31,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.model.SysUiState;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.wm.shell.common.DisplayController;
import org.junit.Before;
@@ -79,7 +79,7 @@ public class OneHandedGestureHandlerTest extends OneHandedTestCase {
@Test
public void testOneHandedManager_registerForDisplayAreaOrganizer() {
- verify(mMockDisplayAreaOrganizer, times(1)).registerTransitionCallback(mGestureHandler);
+ verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mGestureHandler);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedSettingsUtilTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedSettingsUtilTest.java
index f81d047b0f0c..990eb634e46f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedSettingsUtilTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedSettingsUtilTest.java
@@ -40,14 +40,12 @@ import org.junit.runner.RunWith;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class OneHandedSettingsUtilTest extends OneHandedTestCase {
- OneHandedSettingsUtil mOneHandedSettingsUtil;
ContentResolver mContentResolver;
ContentObserver mContentObserver;
boolean mOnChanged;
@Before
public void setUp() {
- mOneHandedSettingsUtil = new OneHandedSettingsUtil();
mContentResolver = mContext.getContentResolver();
mContentObserver = new ContentObserver(mContext.getMainThreadHandler()) {
@Override
@@ -60,20 +58,20 @@ public class OneHandedSettingsUtilTest extends OneHandedTestCase {
@Test
public void testRegisterSecureKeyObserver() {
- final Uri result = mOneHandedSettingsUtil.registerSettingsKeyObserver(
+ final Uri result = OneHandedSettingsUtil.registerSettingsKeyObserver(
Settings.Secure.ONE_HANDED_MODE_ENABLED, mContentResolver, mContentObserver);
assertThat(result).isNotNull();
- mOneHandedSettingsUtil.registerSettingsKeyObserver(
+ OneHandedSettingsUtil.registerSettingsKeyObserver(
Settings.Secure.ONE_HANDED_MODE_ENABLED, mContentResolver, mContentObserver);
}
@Test
public void testUnregisterSecureKeyObserver() {
- mOneHandedSettingsUtil.registerSettingsKeyObserver(
+ OneHandedSettingsUtil.registerSettingsKeyObserver(
Settings.Secure.ONE_HANDED_MODE_ENABLED, mContentResolver, mContentObserver);
- mOneHandedSettingsUtil.unregisterSettingsKeyObserver(mContentResolver, mContentObserver);
+ OneHandedSettingsUtil.unregisterSettingsKeyObserver(mContentResolver, mContentObserver);
assertThat(mOnChanged).isFalse();
@@ -85,19 +83,19 @@ public class OneHandedSettingsUtilTest extends OneHandedTestCase {
@Test
public void testGetSettingsIsOneHandedModeEnabled() {
- assertThat(mOneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
+ assertThat(OneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
mContentResolver)).isAnyOf(true, false);
}
@Test
public void testGetSettingsTapsAppToExit() {
- assertThat(mOneHandedSettingsUtil.getSettingsTapsAppToExit(
+ assertThat(OneHandedSettingsUtil.getSettingsTapsAppToExit(
mContentResolver)).isAnyOf(true, false);
}
@Test
public void testGetSettingsOneHandedModeTimeout() {
- assertThat(mOneHandedSettingsUtil.getSettingsOneHandedModeTimeout(
+ assertThat(OneHandedSettingsUtil.getSettingsOneHandedModeTimeout(
mContentResolver)).isAnyOf(
ONE_HANDED_TIMEOUT_NEVER,
ONE_HANDED_TIMEOUT_SHORT_IN_SECONDS,
@@ -107,7 +105,7 @@ public class OneHandedSettingsUtilTest extends OneHandedTestCase {
@Test
public void testGetSettingsSwipeToNotificationEnabled() {
- assertThat(mOneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
+ assertThat(OneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
mContentResolver)).isAnyOf(true, false);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
index 15881a2e7c18..8ae632dd5a47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTouchHandlerTest.java
@@ -29,7 +29,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.model.SysUiState;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.wm.shell.common.DisplayController;
import org.junit.Before;
@@ -77,8 +77,7 @@ public class OneHandedTouchHandlerTest extends OneHandedTestCase {
@Test
public void testOneHandedManager_registerForDisplayAreaOrganizer() {
- verify(mMockDisplayAreaOrganizer, times(1))
- .registerTransitionCallback(mTouchHandler);
+ verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mTouchHandler);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java
index f2b77a0a936b..c75a8d2f5454 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedTutorialHandlerTest.java
@@ -16,7 +16,6 @@
package com.android.systemui.onehanded;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.testing.AndroidTestingRunner;
@@ -26,7 +25,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.model.SysUiState;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.wm.shell.common.DisplayController;
import org.junit.Before;
@@ -75,7 +74,6 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase {
@Test
public void testOneHandedManager_registerForDisplayAreaOrganizer() {
- verify(mMockDisplayAreaOrganizer, times(1))
- .registerTransitionCallback(mTutorialHandler);
+ verify(mMockDisplayAreaOrganizer).registerTransitionCallback(mTutorialHandler);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedUITest.java b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedUITest.java
index 6db2679ea116..f0e713e42046 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/onehanded/OneHandedUITest.java
@@ -16,8 +16,7 @@
package com.android.systemui.onehanded;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.times;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.Mockito.verify;
import android.os.SystemProperties;
@@ -44,7 +43,6 @@ import org.mockito.MockitoAnnotations;
public class OneHandedUITest extends OneHandedTestCase {
private static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
- boolean mIsSupportOneHandedMode;
CommandQueue mCommandQueue;
KeyguardUpdateMonitor mKeyguardUpdateMonitor;
OneHandedUI mOneHandedUI;
@@ -52,110 +50,58 @@ public class OneHandedUITest extends OneHandedTestCase {
@Mock
OneHandedManagerImpl mMockOneHandedManagerImpl;
@Mock
- OneHandedSettingsUtil mMockSettingsUtil;
- @Mock
OneHandedTimeoutHandler mMockTimeoutHandler;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mIsSupportOneHandedMode = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
mCommandQueue = new CommandQueue(mContext);
mScreenLifecycle = new ScreenLifecycle();
mOneHandedUI = new OneHandedUI(mContext,
mCommandQueue,
mMockOneHandedManagerImpl,
- mMockSettingsUtil,
mScreenLifecycle);
mOneHandedUI.start();
mKeyguardUpdateMonitor = mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
}
+ @Before
+ public void assumeOneHandedModeSupported() {
+ assumeTrue(SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false));
+ }
+
@Test
public void testStartOneHanded() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
mOneHandedUI.startOneHanded();
- verify(mMockOneHandedManagerImpl, times(1)).startOneHanded();
+ verify(mMockOneHandedManagerImpl).startOneHanded();
}
@Test
public void testStopOneHanded() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
mOneHandedUI.stopOneHanded();
- verify(mMockOneHandedManagerImpl, times(1)).stopOneHanded();
- }
-
- @Test
- public void testRegisterSettingsObserver_forEnabled() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
- final String key = Settings.Secure.ONE_HANDED_MODE_ENABLED;
-
- verify(mMockSettingsUtil, times(1)).registerSettingsKeyObserver(key, any(), any());
- }
-
- @Test
- public void testRegisterSettingsObserver_forTimeout() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
- final String key = Settings.Secure.ONE_HANDED_MODE_TIMEOUT;
-
- verify(mMockSettingsUtil, times(1)).registerSettingsKeyObserver(key, any(), any());
- }
-
- @Test
- public void testRegisterSettingsObserver_forTapAppExit() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
- final String key = Settings.Secure.TAPS_APP_TO_EXIT;
-
- verify(mMockSettingsUtil, times(1)).registerSettingsKeyObserver(key, any(), any());
+ verify(mMockOneHandedManagerImpl).stopOneHanded();
}
@Test
public void tesSettingsObserver_updateTapAppToExit() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.TAPS_APP_TO_EXIT, 1);
- verify(mMockOneHandedManagerImpl, times(1)).setTaskChangeToExit(true);
+ verify(mMockOneHandedManagerImpl).setTaskChangeToExit(true);
}
@Test
public void tesSettingsObserver_updateEnabled() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ONE_HANDED_MODE_ENABLED, 1);
- verify(mMockOneHandedManagerImpl, times(1)).setOneHandedEnabled(true);
+ verify(mMockOneHandedManagerImpl).setOneHandedEnabled(true);
}
@Test
public void tesSettingsObserver_updateTimeout() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ONE_HANDED_MODE_TIMEOUT,
OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS);
@@ -166,10 +112,6 @@ public class OneHandedUITest extends OneHandedTestCase {
@Test
public void tesSettingsObserver_updateSwipeToNotification() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, 1);
@@ -179,24 +121,16 @@ public class OneHandedUITest extends OneHandedTestCase {
@Ignore("Clarifying do not receive callback")
@Test
public void testKeyguardBouncerShowing_shouldStopOneHanded() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true);
- verify(mMockOneHandedManagerImpl, times(1)).stopOneHanded();
+ verify(mMockOneHandedManagerImpl).stopOneHanded();
}
@Test
public void testScreenTurningOff_shouldStopOneHanded() {
- // Bypass test if device not support one-handed mode
- if (!mIsSupportOneHandedMode) {
- return;
- }
mScreenLifecycle.dispatchScreenTurningOff();
- verify(mMockOneHandedManagerImpl, times(1)).stopOneHanded();
+ verify(mMockOneHandedManagerImpl).stopOneHanded();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index d338cbf51fb5..9922d3620a57 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -150,7 +150,10 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
return new QSFragment(
new RemoteInputQuickSettingsDisabler(context, mock(ConfigurationController.class),
commandQueue),
- new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()),
+ new InjectionInflationController(
+ SystemUIFactory.getInstance()
+ .getRootComponent()
+ .createViewInstanceCreatorFactory()),
mock(QSTileHost.class),
mock(StatusBarStateController.class),
commandQueue,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 6f46923cda5e..c35ada7c3501 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -212,19 +212,6 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
}
@Test
- public void testUpdateNotificationViews_appOps() throws Exception {
- NotificationEntry entry0 = createEntry();
- entry0.setRow(spy(entry0.getRow()));
- when(mEntryManager.getVisibleNotifications()).thenReturn(
- Lists.newArrayList(entry0));
- mListContainer.addContainerView(entry0.getRow());
-
- mViewHierarchyManager.updateNotificationViews();
-
- verify(entry0.getRow(), times(1)).showAppOpsIcons(any());
- }
-
- @Test
public void testReentrantCallsToOnDynamicPrivacyChangedPostForLater() {
// GIVEN a ListContainer that will make a re-entrant call to updateNotificationViews()
mMadeReentrantCall = false;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java
index 960ea79f36b4..ce8ce2e39bcc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinatorTest.java
@@ -77,8 +77,6 @@ public class AppOpsCoordinatorTest extends SysuiTestCase {
private NotificationEntryBuilder mEntryBuilder;
private AppOpsCoordinator mAppOpsCoordinator;
private NotifFilter mForegroundFilter;
- private NotifCollectionListener mNotifCollectionListener;
- private AppOpsController.Callback mAppOpsCallback;
private NotifLifetimeExtender mForegroundNotifLifetimeExtender;
private NotifSection mFgsSection;
@@ -113,19 +111,6 @@ public class AppOpsCoordinatorTest extends SysuiTestCase {
lifetimeExtenderCaptor.capture());
mForegroundNotifLifetimeExtender = lifetimeExtenderCaptor.getValue();
- // capture notifCollectionListener
- ArgumentCaptor<NotifCollectionListener> notifCollectionCaptor =
- ArgumentCaptor.forClass(NotifCollectionListener.class);
- verify(mNotifPipeline, times(1)).addCollectionListener(
- notifCollectionCaptor.capture());
- mNotifCollectionListener = notifCollectionCaptor.getValue();
-
- // capture app ops callback
- ArgumentCaptor<AppOpsController.Callback> appOpsCaptor =
- ArgumentCaptor.forClass(AppOpsController.Callback.class);
- verify(mAppOpsController).addCallback(any(int[].class), appOpsCaptor.capture());
- mAppOpsCallback = appOpsCaptor.getValue();
-
mFgsSection = mAppOpsCoordinator.getSection();
}
@@ -230,136 +215,6 @@ public class AppOpsCoordinatorTest extends SysuiTestCase {
}
@Test
- public void testAppOpsUpdateOnlyAppliedToRelevantNotificationWithStandardLayout() {
- // GIVEN three current notifications, two with the same key but from different users
- NotificationEntry entry1 = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(1)
- .build();
- NotificationEntry entry2 = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(2)
- .build();
- NotificationEntry entry3_diffUser = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID + 1))
- .setPkg(TEST_PKG)
- .setId(2)
- .build();
- when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry1, entry2, entry3_diffUser));
-
- // GIVEN that only entry2 has a standard layout
- when(mForegroundServiceController.getStandardLayoutKeys(NOTIF_USER_ID, TEST_PKG))
- .thenReturn(new ArraySet<>(List.of(entry2.getKey())));
-
- // WHEN a new app ops code comes in
- mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true);
- mExecutor.runAllReady();
-
- // THEN entry2's app ops are updated, but no one else's are
- assertEquals(
- new ArraySet<>(),
- entry1.mActiveAppOps);
- assertEquals(
- new ArraySet<>(List.of(47)),
- entry2.mActiveAppOps);
- assertEquals(
- new ArraySet<>(),
- entry3_diffUser.mActiveAppOps);
- }
-
- @Test
- public void testAppOpsUpdateAppliedToAllNotificationsWithStandardLayouts() {
- // GIVEN three notifications with standard layouts
- NotificationEntry entry1 = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(1)
- .build();
- NotificationEntry entry2 = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(2)
- .build();
- NotificationEntry entry3 = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(3)
- .build();
- when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry1, entry2, entry3));
- when(mForegroundServiceController.getStandardLayoutKeys(NOTIF_USER_ID, TEST_PKG))
- .thenReturn(new ArraySet<>(List.of(entry1.getKey(), entry2.getKey(),
- entry3.getKey())));
-
- // WHEN a new app ops code comes in
- mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true);
- mExecutor.runAllReady();
-
- // THEN all entries get updated
- assertEquals(
- new ArraySet<>(List.of(47)),
- entry1.mActiveAppOps);
- assertEquals(
- new ArraySet<>(List.of(47)),
- entry2.mActiveAppOps);
- assertEquals(
- new ArraySet<>(List.of(47)),
- entry3.mActiveAppOps);
- }
-
- @Test
- public void testAppOpsAreRemoved() {
- // GIVEN One notification which is associated with app ops
- NotificationEntry entry = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(2)
- .build();
- when(mNotifPipeline.getAllNotifs()).thenReturn(List.of(entry));
- when(mForegroundServiceController.getStandardLayoutKeys(0, TEST_PKG))
- .thenReturn(new ArraySet<>(List.of(entry.getKey())));
-
- // GIVEN that the notification's app ops are already [47, 33]
- mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, true);
- mAppOpsCallback.onActiveStateChanged(33, NOTIF_USER_ID, TEST_PKG, true);
- mExecutor.runAllReady();
- assertEquals(
- new ArraySet<>(List.of(47, 33)),
- entry.mActiveAppOps);
-
- // WHEN one of the app ops is removed
- mAppOpsCallback.onActiveStateChanged(47, NOTIF_USER_ID, TEST_PKG, false);
- mExecutor.runAllReady();
-
- // THEN the entry's active app ops are updated as well
- assertEquals(
- new ArraySet<>(List.of(33)),
- entry.mActiveAppOps);
- }
-
- @Test
- public void testNullAppOps() {
- // GIVEN one notification with app ops
- NotificationEntry entry = new NotificationEntryBuilder()
- .setUser(new UserHandle(NOTIF_USER_ID))
- .setPkg(TEST_PKG)
- .setId(2)
- .build();
- entry.mActiveAppOps.clear();
- entry.mActiveAppOps.addAll(List.of(47, 33));
-
- // WHEN the notification is updated and the foreground service controller returns null for
- // this notification
- when(mForegroundServiceController.getAppOps(entry.getSbn().getUser().getIdentifier(),
- entry.getSbn().getPackageName())).thenReturn(null);
- mNotifCollectionListener.onEntryUpdated(entry);
-
- // THEN the entry's active app ops is updated to empty
- assertTrue(entry.mActiveAppOps.isEmpty());
- }
-
- @Test
public void testIncludeFGSInSection_importanceDefault() {
// GIVEN the notification represents a colorized foreground service with > min importance
mEntryBuilder
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.java
new file mode 100644
index 000000000000..bbe92f67ca2e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferTest.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.render;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.testing.AndroidTestingRunner;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class ShadeViewDifferTest extends SysuiTestCase {
+ private ShadeViewDiffer mDiffer;
+
+ private FakeController mRootController = new FakeController(mContext, "RootController");
+ private FakeController mController1 = new FakeController(mContext, "Controller1");
+ private FakeController mController2 = new FakeController(mContext, "Controller2");
+ private FakeController mController3 = new FakeController(mContext, "Controller3");
+ private FakeController mController4 = new FakeController(mContext, "Controller4");
+ private FakeController mController5 = new FakeController(mContext, "Controller5");
+ private FakeController mController6 = new FakeController(mContext, "Controller6");
+ private FakeController mController7 = new FakeController(mContext, "Controller7");
+
+ @Mock
+ ShadeViewDifferLogger mLogger;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mDiffer = new ShadeViewDiffer(mRootController, mLogger);
+ }
+
+ @Test
+ public void testAddInitialViews() {
+ // WHEN a spec is applied to an empty root
+ // THEN the final tree matches the spec
+ applySpecAndCheck(
+ node(mController1),
+ node(mController2,
+ node(mController3),
+ node(mController4)
+ ),
+ node(mController5)
+ );
+ }
+
+ @Test
+ public void testDetachViews() {
+ // GIVEN a preexisting tree of controllers
+ applySpecAndCheck(
+ node(mController1),
+ node(mController2,
+ node(mController3),
+ node(mController4)
+ ),
+ node(mController5)
+ );
+
+ // WHEN the new spec removes nodes
+ // THEN the final tree matches the spec
+ applySpecAndCheck(
+ node(mController5)
+ );
+ }
+
+ @Test
+ public void testReparentChildren() {
+ // GIVEN a preexisting tree of controllers
+ applySpecAndCheck(
+ node(mController1),
+ node(mController2,
+ node(mController3),
+ node(mController4)
+ ),
+ node(mController5)
+ );
+
+ // WHEN the parents of the controllers are all shuffled around
+ // THEN the final tree matches the spec
+ applySpecAndCheck(
+ node(mController1),
+ node(mController4),
+ node(mController3,
+ node(mController2)
+ )
+ );
+ }
+
+ @Test
+ public void testReorderChildren() {
+ // GIVEN a preexisting tree of controllers
+ applySpecAndCheck(
+ node(mController1),
+ node(mController2),
+ node(mController3),
+ node(mController4)
+ );
+
+ // WHEN the children change order
+ // THEN the final tree matches the spec
+ applySpecAndCheck(
+ node(mController3),
+ node(mController2),
+ node(mController4),
+ node(mController1)
+ );
+ }
+
+ @Test
+ public void testRemovedGroupsAreKeptTogether() {
+ // GIVEN a preexisting tree with a group
+ applySpecAndCheck(
+ node(mController1),
+ node(mController2,
+ node(mController3),
+ node(mController4),
+ node(mController5)
+ )
+ );
+
+ // WHEN the new spec removes the entire group
+ applySpecAndCheck(
+ node(mController1)
+ );
+
+ // THEN the group children are still attached to their parent
+ assertEquals(mController2.getView(), mController3.getView().getParent());
+ assertEquals(mController2.getView(), mController4.getView().getParent());
+ assertEquals(mController2.getView(), mController5.getView().getParent());
+ }
+
+ @Test
+ public void testUnmanagedViews() {
+ // GIVEN a preexisting tree of controllers
+ applySpecAndCheck(
+ node(mController1),
+ node(mController2,
+ node(mController3),
+ node(mController4)
+ ),
+ node(mController5)
+ );
+
+ // GIVEN some additional unmanaged views attached to the tree
+ View unmanagedView1 = new View(mContext);
+ View unmanagedView2 = new View(mContext);
+
+ mRootController.getView().addView(unmanagedView1, 1);
+ mController2.getView().addView(unmanagedView2, 0);
+
+ // WHEN a new spec is applied with additional nodes
+ // THEN the final tree matches the spec
+ applySpecAndCheck(
+ node(mController1),
+ node(mController2,
+ node(mController3),
+ node(mController4),
+ node(mController6)
+ ),
+ node(mController5),
+ node(mController7)
+ );
+
+ // THEN the unmanaged views have been pushed to the end of their parents
+ assertEquals(unmanagedView1, mRootController.view.getChildAt(4));
+ assertEquals(unmanagedView2, mController2.view.getChildAt(3));
+ }
+
+ private void applySpecAndCheck(NodeSpec spec) {
+ mDiffer.applySpec(spec);
+ checkMatchesSpec(spec);
+ }
+
+ private void applySpecAndCheck(SpecBuilder... children) {
+ applySpecAndCheck(node(mRootController, children).build());
+ }
+
+ private void checkMatchesSpec(NodeSpec spec) {
+ final NodeController parent = spec.getController();
+ final List<NodeSpec> children = spec.getChildren();
+
+ for (int i = 0; i < children.size(); i++) {
+ NodeSpec childSpec = children.get(i);
+ View view = parent.getChildAt(i);
+
+ assertEquals(
+ "Child " + i + " of parent " + parent.getNodeLabel() + " should be "
+ + childSpec.getController().getNodeLabel() + " but is instead "
+ + (view != null ? mDiffer.getViewLabel(view) : "null"),
+ view,
+ childSpec.getController().getView());
+
+ if (!childSpec.getChildren().isEmpty()) {
+ checkMatchesSpec(childSpec);
+ }
+ }
+ }
+
+ private static class FakeController implements NodeController {
+
+ public final FrameLayout view;
+ private final String mLabel;
+
+ FakeController(Context context, String label) {
+ view = new FrameLayout(context);
+ mLabel = label;
+ }
+
+ @NonNull
+ @Override
+ public String getNodeLabel() {
+ return mLabel;
+ }
+
+ @NonNull
+ @Override
+ public FrameLayout getView() {
+ return view;
+ }
+
+ @Override
+ public int getChildCount() {
+ return view.getChildCount();
+ }
+
+ @Override
+ public View getChildAt(int index) {
+ return view.getChildAt(index);
+ }
+
+ @Override
+ public void addChildAt(@NonNull NodeController child, int index) {
+ view.addView(child.getView(), index);
+ }
+
+ @Override
+ public void moveChildTo(@NonNull NodeController child, int index) {
+ view.removeView(child.getView());
+ view.addView(child.getView(), index);
+ }
+
+ @Override
+ public void removeChild(@NonNull NodeController child, boolean isTransfer) {
+ view.removeView(child.getView());
+ }
+ }
+
+ private static class SpecBuilder {
+ private final NodeController mController;
+ private final SpecBuilder[] mChildren;
+
+ SpecBuilder(NodeController controller, SpecBuilder... children) {
+ mController = controller;
+ mChildren = children;
+ }
+
+ public NodeSpec build() {
+ return build(null);
+ }
+
+ public NodeSpec build(@Nullable NodeSpec parent) {
+ final NodeSpecImpl spec = new NodeSpecImpl(parent, mController);
+ for (SpecBuilder childBuilder : mChildren) {
+ spec.getChildren().add(childBuilder.build(spec));
+ }
+ return spec;
+ }
+ }
+
+ private static SpecBuilder node(NodeController controller, SpecBuilder... children) {
+ return new SpecBuilder(controller, children);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java
deleted file mode 100644
index 43d8b50bcf72..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/AppOpsInfoTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.statusbar.notification.row;
-
-import static android.app.AppOpsManager.OP_CAMERA;
-import static android.app.AppOpsManager.OP_RECORD_AUDIO;
-import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Notification;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.UserHandle;
-import android.service.notification.StatusBarNotification;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.UiThreadTest;
-import android.util.ArraySet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.CountDownLatch;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@UiThreadTest
-public class AppOpsInfoTest extends SysuiTestCase {
- private static final String TEST_PACKAGE_NAME = "test_package";
- private static final int TEST_UID = 1;
-
- private AppOpsInfo mAppOpsInfo;
- private final PackageManager mMockPackageManager = mock(PackageManager.class);
- private final NotificationGuts mGutsParent = mock(NotificationGuts.class);
- private StatusBarNotification mSbn;
- private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
-
- @Before
- public void setUp() throws Exception {
- // Inflate the layout
- final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
- mAppOpsInfo = (AppOpsInfo) layoutInflater.inflate(R.layout.app_ops_info, null);
- mAppOpsInfo.setGutsParent(mGutsParent);
-
- // PackageManager must return a packageInfo and applicationInfo.
- final PackageInfo packageInfo = new PackageInfo();
- packageInfo.packageName = TEST_PACKAGE_NAME;
- when(mMockPackageManager.getPackageInfo(eq(TEST_PACKAGE_NAME), anyInt()))
- .thenReturn(packageInfo);
- final ApplicationInfo applicationInfo = new ApplicationInfo();
- applicationInfo.uid = TEST_UID; // non-zero
- when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).thenReturn(
- applicationInfo);
-
- mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
- new Notification(), UserHandle.CURRENT, null, 0);
- }
-
- @Test
- public void testBindNotification_SetsTextApplicationName() {
- when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
- final TextView textView = mAppOpsInfo.findViewById(R.id.pkgname);
- assertTrue(textView.getText().toString().contains("App Name"));
- }
-
- @Test
- public void testBindNotification_SetsPackageIcon() {
- final Drawable iconDrawable = mock(Drawable.class);
- when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
- .thenReturn(iconDrawable);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
- final ImageView iconView = mAppOpsInfo.findViewById(R.id.pkgicon);
- assertEquals(iconDrawable, iconView.getDrawable());
- }
-
- @Test
- public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- final CountDownLatch latch = new CountDownLatch(1);
- mAppOpsInfo.bindGuts(mMockPackageManager, (View v, String pkg, int uid,
- ArraySet<Integer> ops) -> {
- assertEquals(TEST_PACKAGE_NAME, pkg);
- assertEquals(expectedOps, ops);
- assertEquals(TEST_UID, uid);
- latch.countDown();
- }, mSbn, mUiEventLogger, expectedOps);
-
- final View settingsButton = mAppOpsInfo.findViewById(R.id.settings);
- settingsButton.performClick();
- // Verify that listener was triggered.
- assertEquals(0, latch.getCount());
- }
-
- @Test
- public void testBindNotification_LogsOpen() throws Exception {
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
- assertEquals(1, mUiEventLogger.numLogs());
- assertEquals(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_OPEN.getId(),
- mUiEventLogger.eventId(0));
- }
-
- @Test
- public void testOk() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- final CountDownLatch latch = new CountDownLatch(1);
- mAppOpsInfo.bindGuts(mMockPackageManager, (View v, String pkg, int uid,
- ArraySet<Integer> ops) -> {
- assertEquals(TEST_PACKAGE_NAME, pkg);
- assertEquals(expectedOps, ops);
- assertEquals(TEST_UID, uid);
- latch.countDown();
- }, mSbn, mUiEventLogger, expectedOps);
-
- final View okButton = mAppOpsInfo.findViewById(R.id.ok);
- okButton.performClick();
- assertEquals(1, latch.getCount());
- verify(mGutsParent, times(1)).closeControls(eq(okButton), anyBoolean());
- }
-
- @Test
- public void testPrompt_camera() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is using the camera.", prompt.getText());
- }
-
- @Test
- public void testPrompt_mic() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_RECORD_AUDIO);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is using the microphone.", prompt.getText());
- }
-
- @Test
- public void testPrompt_overlay() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is displaying over other apps on your screen.", prompt.getText());
- }
-
- @Test
- public void testPrompt_camera_mic() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- expectedOps.add(OP_RECORD_AUDIO);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is using the microphone and camera.", prompt.getText());
- }
-
- @Test
- public void testPrompt_camera_mic_overlay() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- expectedOps.add(OP_RECORD_AUDIO);
- expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is displaying over other apps on your screen and using"
- + " the microphone and camera.", prompt.getText());
- }
-
- @Test
- public void testPrompt_camera_overlay() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_CAMERA);
- expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is displaying over other apps on your screen and using"
- + " the camera.", prompt.getText());
- }
-
- @Test
- public void testPrompt_mic_overlay() {
- ArraySet<Integer> expectedOps = new ArraySet<>();
- expectedOps.add(OP_RECORD_AUDIO);
- expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
- mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
- TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
- assertEquals("This app is displaying over other apps on your screen and using"
- + " the microphone.", prompt.getText());
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index dc4a6ca14a77..f29b46c73e4d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -35,12 +35,10 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.AppOpsManager;
import android.app.NotificationChannel;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
-import android.util.ArraySet;
import android.view.View;
import androidx.test.filters.SmallTest;
@@ -213,46 +211,6 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
}
@Test
- public void testShowAppOps_noHeader() {
- // public notification is custom layout - no header
- mGroupRow.setSensitive(true, true);
- mGroupRow.setAppOpsOnClickListener(null);
- mGroupRow.showAppOpsIcons(null);
- }
-
- @Test
- public void testShowAppOpsIcons_header() {
- NotificationContentView publicLayout = mock(NotificationContentView.class);
- mGroupRow.setPublicLayout(publicLayout);
- NotificationContentView privateLayout = mock(NotificationContentView.class);
- mGroupRow.setPrivateLayout(privateLayout);
- NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
- when(mockContainer.getNotificationChildCount()).thenReturn(1);
- mGroupRow.setChildrenContainer(mockContainer);
-
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
- mGroupRow.showAppOpsIcons(ops);
-
- verify(mockContainer, times(1)).showAppOpsIcons(ops);
- verify(privateLayout, times(1)).showAppOpsIcons(ops);
- verify(publicLayout, times(1)).showAppOpsIcons(ops);
-
- }
-
- @Test
- public void testAppOpsOnClick() {
- ExpandableNotificationRow.CoordinateOnClickListener l = mock(
- ExpandableNotificationRow.CoordinateOnClickListener.class);
- View view = mock(View.class);
-
- mGroupRow.setAppOpsOnClickListener(l);
-
- mGroupRow.getAppOpsOnClickListener().onClick(view);
- verify(l, times(1)).onClick(any(), anyInt(), anyInt(), any());
- }
-
- @Test
public void testFeedback_noHeader() {
// public notification is custom layout - no header
mGroupRow.setSensitive(true, true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
index 6d4a7115b8c4..c2091da2347e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
@@ -76,32 +76,6 @@ public class NotificationContentViewTest extends SysuiTestCase {
@Test
@UiThreadTest
- public void testShowAppOpsIcons() {
- View mockContracted = mock(NotificationHeaderView.class);
- when(mockContracted.findViewById(com.android.internal.R.id.mic))
- .thenReturn(mockContracted);
- View mockExpanded = mock(NotificationHeaderView.class);
- when(mockExpanded.findViewById(com.android.internal.R.id.mic))
- .thenReturn(mockExpanded);
- View mockHeadsUp = mock(NotificationHeaderView.class);
- when(mockHeadsUp.findViewById(com.android.internal.R.id.mic))
- .thenReturn(mockHeadsUp);
-
- mView.setContractedChild(mockContracted);
- mView.setExpandedChild(mockExpanded);
- mView.setHeadsUpChild(mockHeadsUp);
-
- ArraySet<Integer> ops = new ArraySet<>();
- ops.add(AppOpsManager.OP_RECORD_AUDIO);
- mView.showAppOpsIcons(ops);
-
- verify(mockContracted, times(1)).setVisibility(View.VISIBLE);
- verify(mockExpanded, times(1)).setVisibility(View.VISIBLE);
- verify(mockHeadsUp, times(1)).setVisibility(View.VISIBLE);
- }
-
- @Test
- @UiThreadTest
public void testShowFeedbackIcon() {
View mockContracted = mock(NotificationHeaderView.class);
when(mockContracted.findViewById(com.android.internal.R.id.feedback))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
index a90af87064b5..7a0a19bd5424 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
@@ -221,6 +221,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
.thenAnswer((Answer<ExpandableNotificationRowController>) invocation ->
new ExpandableNotificationRowController(
viewCaptor.getValue(),
+ mListContainer,
mock(ActivatableNotificationViewController.class),
mNotificationMediaManager,
mock(PluginManager.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 14994d55852f..54ccc4d8320d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -79,7 +79,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -117,7 +117,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
@Mock private VisualStabilityManager mVisualStabilityManager;
@Mock private NotificationPresenter mPresenter;
@Mock private NotificationActivityStarter mNotificationActivityStarter;
- @Mock private NotificationStackScrollLayout mStackScroller;
+ @Mock private NotificationListContainer mNotificationListContainer;
@Mock private NotificationInfo.CheckSaveListener mCheckSaveListener;
@Mock private OnSettingsClickListener mOnSettingsClickListener;
@Mock private DeviceProvisionedController mDeviceProvisionedController;
@@ -156,7 +156,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
mChannelEditorDialogController, mContextTracker, mProvider,
mAssistantFeedbackController, mBubbleController,
new UiEventLoggerFake());
- mGutsManager.setUpWithPresenter(mPresenter, mStackScroller,
+ mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer,
mCheckSaveListener, mOnSettingsClickListener);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 8ccbb2ebb0db..123be9f92b8a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -422,7 +422,6 @@ public class NotificationTestHelper {
mock(OnExpandClickListener.class),
mock(NotificationMediaManager.class),
mock(ExpandableNotificationRow.CoordinateOnClickListener.class),
- mock(ExpandableNotificationRow.CoordinateOnClickListener.class),
mock(FalsingManager.class),
mStatusBarStateController,
mPeopleNotificationIdentifier);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
index 3e469073694f..ccdc69aeaa18 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
@@ -34,6 +34,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.view.AppearanceRegion;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.policy.BatteryController;
import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
index d1a439f99702..18cb6675f384 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.phone;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -29,6 +28,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -66,6 +66,7 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase {
private NotificationIconAreaController mController;
@Mock
private BubbleController mBubbleController;
+ @Mock private DemoModeController mDemoModeController;
@Before
public void setup() {
@@ -77,7 +78,8 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase {
mController = new NotificationIconAreaController(mContext, mStatusBar,
mStatusBarStateController, mWakeUpCoordinator, mKeyguardBypassController,
- mNotificationMediaManager, mListener, mDozeParameters, mBubbleController);
+ mNotificationMediaManager, mListener, mDozeParameters, mBubbleController,
+ mDemoModeController);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index f66fd5677a5d..a0c0e7979084 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -72,7 +72,6 @@ import com.android.systemui.statusbar.notification.ConversationNotificationManag
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
@@ -188,6 +187,9 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock
private KeyguardClockSwitchController mKeyguardClockSwitchController;
+ @Mock
+ private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
+
private NotificationPanelViewController mNotificationPanelViewController;
private View.AccessibilityDelegate mAccessibiltyDelegate;
@@ -205,8 +207,11 @@ public class NotificationPanelViewTest extends SysuiTestCase {
when(mView.findViewById(R.id.keyguard_clock_container)).thenReturn(mKeyguardClockSwitch);
when(mView.findViewById(R.id.notification_stack_scroller))
.thenReturn(mNotificationStackScrollLayout);
- when(mNotificationStackScrollLayout.getHeight()).thenReturn(1000);
- when(mNotificationStackScrollLayout.getHeadsUpCallback()).thenReturn(mHeadsUpCallback);
+ when(mNotificationStackScrollLayout.getController())
+ .thenReturn(mNotificationStackScrollLayoutController);
+ when(mNotificationStackScrollLayoutController.getHeight()).thenReturn(1000);
+ when(mNotificationStackScrollLayoutController.getHeadsUpCallback())
+ .thenReturn(mHeadsUpCallback);
when(mView.findViewById(R.id.keyguard_bottom_area)).thenReturn(mKeyguardBottomArea);
when(mKeyguardBottomArea.getLeftView()).thenReturn(mock(KeyguardAffordanceView.class));
when(mKeyguardBottomArea.getRightView()).thenReturn(mock(KeyguardAffordanceView.class));
@@ -233,11 +238,6 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mock(NotificationRoundnessManager.class),
mStatusBarStateController,
new FalsingManagerFake());
- NotificationStackScrollLayoutController notificationStackScrollLayoutController =
- new NotificationStackScrollLayoutController(
- true /* allowLongPress */,
- mock(NotificationGutsManager.class)
- );
mNotificationPanelViewController = new NotificationPanelViewController(mView,
mInjectionInflationController,
coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
@@ -251,7 +251,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mConversationNotificationManager, mMediaHiearchyManager,
mBiometricUnlockController, mStatusBarKeyguardViewManager,
() -> mKeyguardClockSwitchController,
- notificationStackScrollLayoutController);
+ mNotificationStackScrollLayoutController);
mNotificationPanelViewController.initDependencies(mStatusBar, mGroupManager,
mNotificationShelfController, mNotificationAreaController, mScrimController);
mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
@@ -267,8 +267,10 @@ public class NotificationPanelViewTest extends SysuiTestCase {
public void testSetDozing_notifiesNsslAndStateController() {
mNotificationPanelViewController.setDozing(true /* dozing */, true /* animate */,
null /* touch */);
- InOrder inOrder = inOrder(mNotificationStackScrollLayout, mStatusBarStateController);
- inOrder.verify(mNotificationStackScrollLayout).setDozing(eq(true), eq(true), eq(null));
+ InOrder inOrder = inOrder(
+ mNotificationStackScrollLayoutController, mStatusBarStateController);
+ inOrder.verify(mNotificationStackScrollLayoutController)
+ .setDozing(eq(true), eq(true), eq(null));
inOrder.verify(mStatusBarStateController).setDozeAmount(eq(1f), eq(true));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
index e04d25b17c71..51900cb7dda1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
@@ -100,7 +100,9 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
mController = new NotificationShadeWindowViewController(
new InjectionInflationController(
- SystemUIFactory.getInstance().getRootComponent()),
+ SystemUIFactory.getInstance()
+ .getRootComponent()
+ .createViewInstanceCreatorFactory()),
mCoordinator,
mPulseExpansionHandler,
mDynamicPrivacyController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 675a2df768d8..50d891efc62c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -43,6 +43,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.NotificationMediaManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 33067343ba40..a71b10cf9264 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -184,7 +184,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
getContext(),
mock(CommandQueue.class),
mHandler,
- mHandler,
mUiBgExecutor,
mEntryManager,
mNotifPipeline,
@@ -234,9 +233,6 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
// set up Handler to synchronously invoke the Runnable arg
doAnswer(answerVoid(Runnable::run))
.when(mHandler).post(any(Runnable.class));
-
- doAnswer(answerVoid(Runnable::run))
- .when(mHandler).postAtFrontOfQueue(any(Runnable.class));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 318e9b87fa70..e4f481241257 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -23,13 +23,11 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.StatusBarManager;
-import android.content.Context;
import android.metrics.LogMaker;
import android.support.test.metricshelper.MetricsAsserts;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
-import android.view.ViewGroup;
import androidx.test.filters.SmallTest;
@@ -59,6 +57,8 @@ import com.android.systemui.statusbar.notification.interruption.NotificationInte
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
@@ -112,11 +112,17 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
NotificationShadeWindowView notificationShadeWindowView =
mock(NotificationShadeWindowView.class);
+ NotificationStackScrollLayoutController stackScrollLayoutController =
+ mock(NotificationStackScrollLayoutController.class);
+ when(stackScrollLayoutController.getView()).thenReturn(
+ mock(NotificationStackScrollLayout.class));
+ when(stackScrollLayoutController.getNotificationListContainer()).thenReturn(
+ mock(NotificationListContainer.class));
when(notificationShadeWindowView.getResources()).thenReturn(mContext.getResources());
mStatusBarNotificationPresenter = new StatusBarNotificationPresenter(mContext,
mock(NotificationPanelViewController.class), mock(HeadsUpManagerPhone.class),
- notificationShadeWindowView, mock(NotificationListContainerViewGroup.class),
+ notificationShadeWindowView, stackScrollLayoutController,
mock(DozeScrimController.class), mock(ScrimController.class),
mock(ActivityLaunchAnimator.class), mock(DynamicPrivacyController.class),
mock(KeyguardStateController.class),
@@ -205,14 +211,4 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
new LogMaker(MetricsEvent.ACTION_LS_NOTE)
.setType(MetricsEvent.TYPE_ACTION));
}
-
- // We need this because mockito doesn't know how to construct a mock that extends ViewGroup
- // and implements NotificationListContainer without it because of classloader issues.
- private abstract static class NotificationListContainerViewGroup extends ViewGroup
- implements NotificationListContainer {
-
- public NotificationListContainerViewGroup(Context context) {
- super(context);
- }
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 5a08c9ca017b..aa0940698510 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -83,10 +83,12 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.PluginDependencyProvider;
@@ -97,7 +99,6 @@ import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.NavigationBarController;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -124,7 +125,9 @@ import com.android.systemui.statusbar.notification.interruption.NotificationInte
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.logging.NotificationPanelLoggerFake;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -171,6 +174,8 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private KeyguardStateController mKeyguardStateController;
@Mock private KeyguardIndicationController mKeyguardIndicationController;
@Mock private NotificationStackScrollLayout mStackScroller;
+ @Mock private NotificationStackScrollLayoutController mStackScrollerController;
+ @Mock private NotificationListContainer mNotificationListContainer;
@Mock private HeadsUpManagerPhone mHeadsUpManager;
@Mock private NotificationPanelViewController mNotificationPanelViewController;
@Mock private NotificationPanelView mNotificationPanelView;
@@ -248,6 +253,7 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private ExtensionController mExtensionController;
@Mock private UserInfoControllerImpl mUserInfoControllerImpl;
@Mock private PhoneStatusBarPolicy mPhoneStatusBarPolicy;
+ @Mock private DemoModeController mDemoModeController;
@Mock private Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
private ShadeController mShadeController;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -283,6 +289,10 @@ public class StatusBarTest extends SysuiTestCase {
mContext.setTheme(R.style.Theme_SystemUI_Light);
+ when(mStackScroller.getController()).thenReturn(mStackScrollerController);
+ when(mStackScrollerController.getView()).thenReturn(mStackScroller);
+ when(mStackScrollerController.getNotificationListContainer()).thenReturn(
+ mNotificationListContainer);
when(mStackScroller.generateLayoutParams(any())).thenReturn(new LayoutParams(0, 0));
when(mNotificationPanelViewController.getView()).thenReturn(mNotificationPanelView);
when(mNotificationPanelView.getLayoutParams()).thenReturn(new LayoutParams(0, 0));
@@ -403,6 +413,7 @@ public class StatusBarTest extends SysuiTestCase {
mPhoneStatusBarPolicy,
mKeyguardIndicationController,
mDismissCallbackRegistry,
+ mDemoModeController,
mNotificationShadeDepthControllerLazy,
mStatusBarTouchableRegionManager);
@@ -429,7 +440,7 @@ public class StatusBarTest extends SysuiTestCase {
mStatusBar.mStackScroller = mStackScroller;
mStatusBar.startKeyguard();
mInitController.executePostInitTasks();
- notificationLogger.setUpWithContainer(mStackScroller);
+ notificationLogger.setUpWithContainer(mNotificationListContainer);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index eca48c8c2ee1..23fa6fd5e4ca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -29,6 +29,7 @@ import android.testing.TestableLooper;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.power.EnhancedEstimates;
import org.junit.Assert;
@@ -44,17 +45,21 @@ import org.mockito.MockitoAnnotations;
@TestableLooper.RunWithLooper
public class BatteryControllerTest extends SysuiTestCase {
- @Mock
- private PowerManager mPowerManager;
- @Mock
- private BroadcastDispatcher mBroadcastDispatcher;
+ @Mock private PowerManager mPowerManager;
+ @Mock private BroadcastDispatcher mBroadcastDispatcher;
+ @Mock private DemoModeController mDemoModeController;
private BatteryControllerImpl mBatteryController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mBatteryController = new BatteryControllerImpl(getContext(), mock(EnhancedEstimates.class),
- mPowerManager, mBroadcastDispatcher, new Handler(), new Handler());
+ mBatteryController = new BatteryControllerImpl(getContext(),
+ mock(EnhancedEstimates.class),
+ mPowerManager,
+ mBroadcastDispatcher,
+ mDemoModeController,
+ new Handler(),
+ new Handler());
mBatteryController.init();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index aef454fc1374..7db1b836f428 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -66,6 +66,7 @@ import com.android.settingslib.net.DataUsageController;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
@@ -113,6 +114,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
protected DeviceProvisionedController mMockProvisionController;
protected DeviceProvisionedListener mUserCallback;
protected Instrumentation mInstrumentation;
+ protected DemoModeController mDemoModeController;
protected int mSubId;
@@ -146,6 +148,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
res.addOverride(R.string.cell_data_off_content_description, NO_DATA_STRING);
res.addOverride(R.string.not_default_data_content_description, NOT_DEFAULT_DATA_STRING);
+ mDemoModeController = mock(DemoModeController.class);
mMockWm = mock(WifiManager.class);
mMockTm = mock(TelephonyManager.class);
mMockSm = mock(SubscriptionManager.class);
@@ -200,10 +203,21 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
return null;
}).when(mMockProvisionController).addCallback(any());
- mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
- mMockNsm, mMockSm, mConfig, TestableLooper.get(this).getLooper(), mCallbackHandler,
- mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
- mMockSubDefaults, mMockProvisionController, mMockBd);
+ mNetworkController = new NetworkControllerImpl(mContext,
+ mMockCm,
+ mMockTm,
+ mMockWm,
+ mMockNsm,
+ mMockSm,
+ mConfig,
+ TestableLooper.get(this).getLooper(),
+ mCallbackHandler,
+ mock(AccessPointControllerImpl.class),
+ mock(DataUsageController.class),
+ mMockSubDefaults,
+ mMockProvisionController,
+ mMockBd,
+ mDemoModeController);
setupNetworkController();
// Trigger blank callbacks to always get the current state (some tests don't trigger
@@ -254,7 +268,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
mConfig, TestableLooper.get(this).getLooper(), mCallbackHandler,
mock(AccessPointControllerImpl.class),
mock(DataUsageController.class), mMockSubDefaults,
- mock(DeviceProvisionedController.class), mMockBd);
+ mock(DeviceProvisionedController.class), mMockBd, mDemoModeController);
setupNetworkController();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 6fffcff41a4f..d8aa29e9f766 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -106,7 +106,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
mock(AccessPointControllerImpl.class),
mock(DataUsageController.class), mMockSubDefaults,
- mock(DeviceProvisionedController.class), mMockBd);
+ mock(DeviceProvisionedController.class), mMockBd, mDemoModeController);
setupNetworkController();
setupDefaultSignal();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 3b2743775721..61f71b758d80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -63,7 +63,8 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
- mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd);
+ mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
+ mDemoModeController);
setupNetworkController();
verifyLastMobileDataIndicators(false, -1, 0);
@@ -81,7 +82,8 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
- mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd);
+ mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
+ mDemoModeController);
mNetworkController.registerListeners();
// Wait for the main looper to execute the previous command
@@ -147,7 +149,8 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
- mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd);
+ mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
+ mDemoModeController);
setupNetworkController();
// No Subscriptions.
diff --git a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index 9bb01ae5df1d..64be2d9a5599 100644
--- a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -50,7 +50,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.HandlerUtils;
import com.android.testutils.TapPacketReader;
import org.junit.After;
@@ -366,7 +366,7 @@ public class EthernetTetheringTest {
private TapPacketReader makePacketReader(FileDescriptor fd, int mtu) {
final TapPacketReader reader = new TapPacketReader(mHandler, fd, mtu);
mHandler.post(() -> reader.start());
- HandlerUtilsKt.waitForIdle(mHandler, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS);
return reader;
}
diff --git a/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java b/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java
index 1499f3be224e..91c7771cc7fe 100644
--- a/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/util/TetheringUtilsTest.java
@@ -27,7 +27,7 @@ import android.net.TetheringRequestParcel;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.testutils.MiscAssertsKt;
+import com.android.testutils.MiscAsserts;
import org.junit.Before;
import org.junit.Test;
@@ -82,6 +82,6 @@ public class TetheringUtilsTest {
request.showProvisioningUi = false;
assertFalse(TetheringUtils.isTetheringRequestEquals(mTetheringRequest, request));
- MiscAssertsKt.assertFieldCountEquals(5, TetheringRequestParcel.class);
+ MiscAsserts.assertFieldCountEquals(5, TetheringRequestParcel.class);
}
}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
index b291438937c7..ce52ae22ece8 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadControllerTest.java
@@ -30,8 +30,8 @@ import static com.android.networkstack.tethering.OffloadController.StatsType.STA
import static com.android.networkstack.tethering.OffloadController.StatsType.STATS_PER_UID;
import static com.android.networkstack.tethering.OffloadHardwareInterface.ForwardedStats;
import static com.android.networkstack.tethering.TetheringConfiguration.DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS;
-import static com.android.testutils.MiscAssertsKt.assertContainsAll;
-import static com.android.testutils.MiscAssertsKt.assertThrows;
+import static com.android.testutils.MiscAsserts.assertContainsAll;
+import static com.android.testutils.MiscAsserts.assertThrows;
import static com.android.testutils.NetworkStatsUtilsKt.assertNetworkStatsEquals;
import static junit.framework.Assert.assertNotNull;
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 46fe5cf093fd..1fe3840b51a8 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -143,7 +143,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.StateMachine;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.testutils.MiscAssertsKt;
+import com.android.testutils.MiscAsserts;
import org.junit.After;
import org.junit.AfterClass;
@@ -1360,7 +1360,7 @@ public class TetheringTest {
assertEquals(0, parcel.localOnlyList.length);
assertEquals(0, parcel.erroredIfaceList.length);
assertEquals(0, parcel.lastErrorList.length);
- MiscAssertsKt.assertFieldCountEquals(5, TetherStatesParcel.class);
+ MiscAsserts.assertFieldCountEquals(5, TetherStatesParcel.class);
}
@Test
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index c45da8668087..a2d58c8019fc 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -631,7 +631,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
// Two pointers moving in the same direction within
// a given distance perform a drag.
mState.startDragging();
- adjustEventLocationForDrag(event);
+ computeDraggingPointerIdIfNeeded(event);
pointerIdBits = 1 << mDraggingPointerId;
event.setEdgeFlags(mReceivedPointerTracker.getLastReceivedDownEdgeFlags());
mDispatcher.sendMotionEvent(
@@ -794,7 +794,7 @@ public class TouchExplorer extends BaseEventStreamTransformation
case 2:
if (isDraggingGesture(event)) {
// If still dragging send a drag event.
- adjustEventLocationForDrag(event);
+ computeDraggingPointerIdIfNeeded(event);
mDispatcher.sendMotionEvent(
event, ACTION_MOVE, rawEvent, pointerIdBits, policyFlags);
} else {
@@ -959,44 +959,27 @@ public class TouchExplorer extends BaseEventStreamTransformation
}
/**
- * Adjust the location of an injected event when performing a drag. The location will be the
- * location of the finger closest to an edge of the screen.
+ * Computes {@link #mDraggingPointerId} if it is invalid. The pointer will be the finger
+ * closet to an edge of the screen.
*/
- private void adjustEventLocationForDrag(MotionEvent event) {
+ private void computeDraggingPointerIdIfNeeded(MotionEvent event) {
+ if (mDraggingPointerId != INVALID_POINTER_ID) {
+ // If we have a valid pointer ID, we should be good
+ final int pointerIndex = event.findPointerIndex(mDraggingPointerId);
+ if (event.findPointerIndex(pointerIndex) >= 0) {
+ return;
+ }
+ }
+ // Use the pointer that is closest to its closest edge.
final float firstPtrX = event.getX(0);
final float firstPtrY = event.getY(0);
final int firstPtrId = event.getPointerId(0);
final float secondPtrX = event.getX(1);
final float secondPtrY = event.getY(1);
final int secondPtrId = event.getPointerId(1);
- float draggingX = firstPtrX;
- float draggingY = firstPtrY;
- if (mDraggingPointerId != INVALID_POINTER_ID) {
- // Just use the coordinates of the dragging pointer.
- int pointerIndex = event.findPointerIndex(mDraggingPointerId);
- if (pointerIndex >= 0) {
- draggingX = event.getX(pointerIndex);
- draggingY = event.getY(pointerIndex);
- } else {
- // We've lost track of the dragging pointer. Try to recover by invalidating it.
- // We'll the drop into the code below to choose a new one.
- mDraggingPointerId = INVALID_POINTER_ID;
- }
- }
- // Not quite an else, since the above code can invalidate the pointer
- if (mDraggingPointerId == INVALID_POINTER_ID) {
- // The goal is to use the coordinates of the finger that is closest to its closest edge.
- if (getDistanceToClosestEdge(firstPtrX, firstPtrY)
- < getDistanceToClosestEdge(secondPtrX, secondPtrY)) {
- // X and Y initialized to firstPtrX and Y was right
- mDraggingPointerId = firstPtrId;
- } else {
- draggingX = secondPtrX;
- draggingY = secondPtrY;
- mDraggingPointerId = secondPtrId;
- }
- }
- event.setLocation(draggingX, draggingY);
+ mDraggingPointerId = (getDistanceToClosestEdge(firstPtrX, firstPtrY)
+ < getDistanceToClosestEdge(secondPtrX, secondPtrY))
+ ? firstPtrId : secondPtrId;
}
private float getDistanceToClosestEdge(float x, float y) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 663fd6259fd4..ad85784ca066 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -360,7 +360,7 @@ public final class AutofillManagerService
@Override // from SystemService
public boolean isUserSupported(TargetUser user) {
- return user.getUserInfo().isFull() || user.getUserInfo().isManagedProfile();
+ return user.isFull() || user.isManagedProfile();
}
@Override // from SystemService
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 29235dd1ee72..e68c07ed73f7 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -441,6 +441,7 @@ public class UserBackupManagerService {
private long mAncestralToken = 0;
private long mCurrentToken = 0;
@Nullable private File mAncestralSerialNumberFile;
+ @OperationType private volatile long mAncestralOperationType;
private final ContentObserver mSetupObserver;
private final BroadcastReceiver mRunInitReceiver;
@@ -881,6 +882,10 @@ public class UserBackupManagerService {
mAncestralToken = ancestralToken;
}
+ public void setAncestralOperationType(@OperationType int operationType) {
+ mAncestralOperationType = operationType;
+ }
+
public long getCurrentToken() {
return mCurrentToken;
}
@@ -1808,6 +1813,16 @@ public class UserBackupManagerService {
}
}
+ private BackupEligibilityRules getEligibilityRulesForRestoreAtInstall(long restoreToken) {
+ if (mAncestralOperationType == OperationType.MIGRATION && restoreToken == mAncestralToken) {
+ return getEligibilityRulesForOperation(OperationType.MIGRATION);
+ } else {
+ // If we're not using the ancestral data set, it means we're restoring from a backup
+ // that happened on this device.
+ return mScheduledBackupEligibility;
+ }
+ }
+
/**
* Get the restore-set token for the best-available restore set for this {@code packageName}:
* the active set if possible, else the ancestral one. Returns zero if none available.
@@ -3976,7 +3991,7 @@ public class UserBackupManagerService {
packageName,
token,
listener,
- mScheduledBackupEligibility);
+ getEligibilityRulesForRestoreAtInstall(restoreSet));
mBackupHandler.sendMessage(msg);
} catch (Exception e) {
// Calling into the transport broke; back off and proceed with the installation.
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index 622067999f27..b9625397d237 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -27,6 +27,7 @@ import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERA
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
+import android.app.backup.BackupManager;
import android.app.backup.FullBackup;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IFullBackupRestoreObserver;
@@ -633,7 +634,11 @@ public class FullRestoreEngine extends RestoreEngine {
setRunning(false);
}
- private static boolean isRestorableFile(FileMetadata info) {
+ private boolean isRestorableFile(FileMetadata info) {
+ if (mBackupEligibilityRules.getOperationType() == BackupManager.OperationType.MIGRATION) {
+ // Everything is eligible for device-to-device migration.
+ return true;
+ }
if (FullBackup.CACHE_TREE_TOKEN.equals(info.domain)) {
if (MORE_DEBUG) {
Slog.i(TAG, "Dropping cache file path " + info.path);
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 7baf55992770..abf11bd542a1 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -1136,6 +1136,8 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
if (mIsSystemRestore && mPmAgent != null) {
backupManagerService.setAncestralPackages(mPmAgent.getRestoredPackages());
backupManagerService.setAncestralToken(mToken);
+ backupManagerService.setAncestralOperationType(
+ mBackupEligibilityRules.getOperationType());
backupManagerService.writeRestoreTokens();
}
diff --git a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
index d6598975a647..73ba1f19c092 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java
@@ -85,12 +85,15 @@ public class BackupEligibilityRules {
* <li>they run as a system-level uid but do not supply their own backup agent
* <li>it is the special shared-storage backup package used for 'adb backup'
* </ol>
+ *
+ * However, the above eligibility rules are ignored for non-system apps in in case of
+ * device-to-device migration, see {@link OperationType}.
*/
@VisibleForTesting
public boolean appIsEligibleForBackup(ApplicationInfo app) {
- // 1. their manifest states android:allowBackup="false"
- boolean appAllowsBackup = (app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0;
- if (!appAllowsBackup && !forceFullBackup(app.uid, mOperationType)) {
+ // 1. their manifest states android:allowBackup="false" and this is not a device-to-device
+ // migration
+ if (!isAppBackupAllowed(app)) {
return false;
}
@@ -123,6 +126,23 @@ public class BackupEligibilityRules {
}
/**
+ * Check if this app allows backup. Apps can opt out of backup by stating
+ * android:allowBackup="false" in their manifest. However, this flag is ignored for non-system
+ * apps during device-to-device migrations, see {@link OperationType}.
+ *
+ * @param app The app under check.
+ * @return boolean indicating whether backup is allowed.
+ */
+ public boolean isAppBackupAllowed(ApplicationInfo app) {
+ if (mOperationType == OperationType.MIGRATION && !UserHandle.isCore(app.uid)) {
+ // Backup / restore of all apps is force allowed during device-to-device migration.
+ return true;
+ }
+
+ return (app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0;
+ }
+
+ /**
* Returns whether an app is eligible for backup at runtime. That is, the app has to:
* <ol>
* <li>Return true for {@link #appIsEligibleForBackup(ApplicationInfo, int)}
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
index bf8e9c8512ae..3789fa14e87b 100644
--- a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -402,7 +402,7 @@ public class TarBackupReader {
info.packageName, PackageManager.GET_SIGNING_CERTIFICATES, userId);
// Fall through to IGNORE if the app explicitly disallows backup
final int flags = pkgInfo.applicationInfo.flags;
- if ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) {
+ if (eligibilityRules.isAppBackupAllowed(pkgInfo.applicationInfo)) {
// Restore system-uid-space packages only if they have
// defined a custom backup agent
if (!UserHandle.isCore(pkgInfo.applicationInfo.uid)
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index ea94ad0b3c20..e742015916e7 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -219,7 +219,7 @@ public final class ContentCaptureManagerService extends
@Override // from SystemService
public boolean isUserSupported(TargetUser user) {
- return user.getUserInfo().isFull() || user.getUserInfo().isManagedProfile();
+ return user.isFull() || user.isManagedProfile();
}
@Override // from SystemService
diff --git a/services/core/java/android/os/UserManagerInternal.java b/services/core/java/android/os/UserManagerInternal.java
index fbe8c04bd59c..61e8128bd510 100644
--- a/services/core/java/android/os/UserManagerInternal.java
+++ b/services/core/java/android/os/UserManagerInternal.java
@@ -262,8 +262,7 @@ public abstract class UserManagerInternal {
public abstract boolean hasUserRestriction(String restriction, int userId);
/**
- * Gets an {@link UserInfo} for the given {@code userId}, or {@code null} if not
- * found.
+ * Gets a {@link UserInfo} for the given {@code userId}, or {@code null} if not found.
*/
public abstract @Nullable UserInfo getUserInfo(@UserIdInt int userId);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index ef62a991f323..bd590d317910 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -4966,7 +4966,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
Slog.w(TAG, "User " + userId + " has no Vpn configuration");
return null;
}
- return vpn.getLockdownWhitelist();
+ return vpn.getLockdownAllowlist();
}
}
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 6402e07bddc3..b2f0c8376db1 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -1477,7 +1477,7 @@ public class IpSecService extends IIpSecService.Stub {
}
/**
- * Checks an IpSecConfig parcel to ensure that the contents are sane and throws an
+ * Checks an IpSecConfig parcel to ensure that the contents are valid and throws an
* IllegalArgumentException if they are not.
*/
private void checkIpSecConfig(IpSecConfig config) {
diff --git a/services/core/java/com/android/server/ServiceWatcher.java b/services/core/java/com/android/server/ServiceWatcher.java
index 0038dc2e8da0..b78b5d945a08 100644
--- a/services/core/java/com/android/server/ServiceWatcher.java
+++ b/services/core/java/com/android/server/ServiceWatcher.java
@@ -238,24 +238,13 @@ public class ServiceWatcher implements ServiceConnection {
new PackageMonitor() {
@Override
- public void onPackageUpdateFinished(String packageName, int uid) {
- ServiceWatcher.this.onPackageChanged(packageName);
- }
-
- @Override
- public void onPackageAdded(String packageName, int uid) {
- ServiceWatcher.this.onPackageChanged(packageName);
- }
-
- @Override
- public void onPackageRemoved(String packageName, int uid) {
- ServiceWatcher.this.onPackageChanged(packageName);
+ public boolean onPackageChanged(String packageName, int uid, String[] components) {
+ return true;
}
@Override
- public boolean onPackageChanged(String packageName, int uid, String[] components) {
- ServiceWatcher.this.onPackageChanged(packageName);
- return super.onPackageChanged(packageName, uid, components);
+ public void onSomePackagesChanged() {
+ onBestServiceChanged(false);
}
}.register(mContext, UserHandle.ALL, true, mHandler);
@@ -320,7 +309,7 @@ public class ServiceWatcher implements ServiceConnection {
if (!mTargetService.equals(ServiceInfo.NONE)) {
if (D) {
- Log.i(TAG, "[" + mIntent.getAction() + "] unbinding from " + mTargetService);
+ Log.d(TAG, "[" + mIntent.getAction() + "] unbinding from " + mTargetService);
}
mContext.unbindService(this);
@@ -335,9 +324,7 @@ public class ServiceWatcher implements ServiceConnection {
Preconditions.checkState(mTargetService.component != null);
- if (D) {
- Log.i(TAG, getLogPrefix() + " binding to " + mTargetService);
- }
+ Log.i(TAG, getLogPrefix() + " binding to " + mTargetService);
Intent bindIntent = new Intent(mIntent).setComponent(mTargetService.component);
if (!mContext.bindServiceAsUser(bindIntent, this,
@@ -355,7 +342,7 @@ public class ServiceWatcher implements ServiceConnection {
Preconditions.checkState(mBinder == null);
if (D) {
- Log.i(TAG, getLogPrefix() + " connected to " + component.toShortString());
+ Log.d(TAG, getLogPrefix() + " connected to " + component.toShortString());
}
mBinder = binder;
@@ -379,7 +366,7 @@ public class ServiceWatcher implements ServiceConnection {
}
if (D) {
- Log.i(TAG, getLogPrefix() + " disconnected from " + component.toShortString());
+ Log.d(TAG, getLogPrefix() + " disconnected from " + component.toShortString());
}
mBinder = null;
@@ -392,13 +379,16 @@ public class ServiceWatcher implements ServiceConnection {
public final void onBindingDied(ComponentName component) {
Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
- if (D) {
- Log.i(TAG, getLogPrefix() + " " + component.toShortString() + " died");
- }
+ Log.i(TAG, getLogPrefix() + " " + component.toShortString() + " died");
onBestServiceChanged(true);
}
+ @Override
+ public final void onNullBinding(ComponentName component) {
+ Log.e(TAG, getLogPrefix() + " " + component.toShortString() + " has null binding");
+ }
+
void onUserSwitched(@UserIdInt int userId) {
mCurrentUserId = userId;
onBestServiceChanged(false);
@@ -410,11 +400,6 @@ public class ServiceWatcher implements ServiceConnection {
}
}
- void onPackageChanged(String packageName) {
- // force a rebind if the changed package was the currently connected package
- onBestServiceChanged(packageName.equals(mTargetService.getPackageName()));
- }
-
/**
* Runs the given function asynchronously if and only if currently connected. Suppresses any
* RemoteException thrown during execution.
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index eca6036ebf8e..d1d9c0e3a285 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3282,7 +3282,7 @@ class StorageManagerService extends IStorageManager.Stub
final UserManagerInternal umInternal =
LocalServices.getService(UserManagerInternal.class);
- for (UserInfo user : um.getUsers(false /* includeDying */)) {
+ for (UserInfo user : um.getUsers()) {
final int flags;
if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
diff --git a/services/core/java/com/android/server/SystemService.java b/services/core/java/com/android/server/SystemService.java
index 1496e926b95b..84d01ec3598d 100644
--- a/services/core/java/com/android/server/SystemService.java
+++ b/services/core/java/com/android/server/SystemService.java
@@ -23,6 +23,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.SystemApi.Client;
+import android.annotation.UserIdInt;
import android.app.ActivityThread;
import android.content.Context;
import android.content.pm.UserInfo;
@@ -131,45 +132,89 @@ public abstract class SystemService {
*/
@SystemApi(client = Client.SYSTEM_SERVER)
public static final class TargetUser {
- @NonNull
- private final UserInfo mUserInfo;
+
+ // NOTE: attributes below must be immutable while ther user is running (i.e., from the
+ // moment it's started until after it's shutdown).
+ private final @UserIdInt int mUserId;
+ private final boolean mFull;
+ private final boolean mManagedProfile;
+ private final boolean mPreCreated;
/** @hide */
public TargetUser(@NonNull UserInfo userInfo) {
- mUserInfo = userInfo;
+ mUserId = userInfo.id;
+ mFull = userInfo.isFull();
+ mManagedProfile = userInfo.isManagedProfile();
+ mPreCreated = userInfo.preCreated;
}
/**
- * @return The information about the user. <b>NOTE: </b> this is a "live" object
- * referenced by {@link UserManagerService} and hence should not be modified.
+ * Checks if the target user is {@link UserInfo#isFull() full}.
*
* @hide
*/
- @NonNull
- public UserInfo getUserInfo() {
- return mUserInfo;
+ public boolean isFull() {
+ return mFull;
+ }
+
+ /**
+ * Checks if the target user is a managed profile.
+ *
+ * @hide
+ */
+ public boolean isManagedProfile() {
+ return mManagedProfile;
+ }
+
+ /**
+ * Checks if the target user is a pre-created user.
+ *
+ * @hide
+ */
+ public boolean isPreCreated() {
+ return mPreCreated;
}
/**
- * @return the target {@link UserHandle}.
+ * Gets the target user's {@link UserHandle}.
*/
@NonNull
public UserHandle getUserHandle() {
- return mUserInfo.getUserHandle();
+ return UserHandle.of(mUserId);
}
/**
- * @return the integer user id
+ * Gets the target user's id.
*
* @hide
*/
- public int getUserIdentifier() {
- return mUserInfo.id;
+ public @UserIdInt int getUserIdentifier() {
+ return mUserId;
}
@Override
public String toString() {
- return Integer.toString(getUserIdentifier());
+ return Integer.toString(mUserId);
+ }
+
+ /**
+ * @hide
+ */
+ public void dump(@NonNull StringBuilder builder) {
+ builder.append(getUserIdentifier());
+
+ if (!isFull() && !isManagedProfile()) return;
+
+ builder.append('(');
+ boolean addComma = false;
+ if (isFull()) {
+ builder.append("full");
+ }
+ if (isManagedProfile()) {
+ if (addComma) builder.append(',');
+ builder.append("mp");
+ }
+ builder.append(')');
}
}
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index 74bb7d7e90f1..df966c1ea6ac 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -27,7 +27,10 @@ import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.util.ArrayMap;
import android.util.Slog;
+import android.util.SparseArray;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
import com.android.server.SystemService.TargetUser;
import com.android.server.utils.TimingsTraceAndSlog;
@@ -74,6 +77,13 @@ public class SystemServiceManager {
private UserManagerInternal mUserManagerInternal;
+ /**
+ * Map of started {@link TargetUser TargetUsers} by user id; users are added on start and
+ * removed after they're completely shut down.
+ */
+ @GuardedBy("mTargetUsers")
+ private final SparseArray<TargetUser> mTargetUsers = new SparseArray<>();
+
SystemServiceManager(Context context) {
mContext = context;
}
@@ -240,21 +250,26 @@ public class SystemServiceManager {
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
}
- private @NonNull UserInfo getUserInfo(@UserIdInt int userHandle) {
- if (mUserManagerInternal == null) {
- throw new IllegalStateException("mUserManagerInternal not set yet");
+ private @NonNull TargetUser getTargetUser(@UserIdInt int userHandle) {
+ final TargetUser targetUser;
+ synchronized (mTargetUsers) {
+ targetUser = mTargetUsers.get(userHandle);
}
- final UserInfo userInfo = mUserManagerInternal.getUserInfo(userHandle);
- if (userInfo == null) {
- throw new IllegalStateException("No UserInfo for " + userHandle);
- }
- return userInfo;
+ Preconditions.checkState(targetUser != null, "No TargetUser for " + userHandle);
+ return targetUser;
}
/**
* Starts the given user.
*/
public void startUser(final @NonNull TimingsTraceAndSlog t, final @UserIdInt int userHandle) {
+ // Create cached TargetUser
+ final UserInfo userInfo = mUserManagerInternal.getUserInfo(userHandle);
+ Preconditions.checkState(userInfo != null, "No UserInfo for " + userHandle);
+ synchronized (mTargetUsers) {
+ mTargetUsers.put(userHandle, new TargetUser(userInfo));
+ }
+
onUser(t, START, userHandle);
}
@@ -291,6 +306,11 @@ public class SystemServiceManager {
*/
public void cleanupUser(final @UserIdInt int userHandle) {
onUser(CLEANUP, userHandle);
+
+ // Remove cached TargetUser
+ synchronized (mTargetUsers) {
+ mTargetUsers.remove(userHandle);
+ }
}
private void onUser(@NonNull String onWhat, @UserIdInt int userHandle) {
@@ -306,9 +326,9 @@ public class SystemServiceManager {
@UserIdInt int curUserId, @UserIdInt int prevUserId) {
t.traceBegin("ssm." + onWhat + "User-" + curUserId);
Slog.i(TAG, "Calling on" + onWhat + "User " + curUserId);
- final TargetUser curUser = new TargetUser(getUserInfo(curUserId));
+ final TargetUser curUser = getTargetUser(curUserId);
final TargetUser prevUser = prevUserId == UserHandle.USER_NULL ? null
- : new TargetUser(getUserInfo(prevUserId));
+ : getTargetUser(prevUserId);
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
@@ -437,7 +457,7 @@ public class SystemServiceManager {
*/
public void dump() {
StringBuilder builder = new StringBuilder();
- builder.append("Current phase: ").append(mCurrentPhase).append("\n");
+ builder.append("Current phase: ").append(mCurrentPhase).append('\n');
builder.append("Services:\n");
final int startedLen = mServices.size();
for (int i = 0; i < startedLen; i++) {
@@ -447,6 +467,14 @@ public class SystemServiceManager {
.append("\n");
}
+ builder.append("Target users: ");
+ final int targetUsersSize = mTargetUsers.size();
+ for (int i = 0; i < targetUsersSize; i++) {
+ mTargetUsers.valueAt(i).dump(builder);
+ if (i != targetUsersSize - 1) builder.append(',');
+ }
+ builder.append('\n');
+
Slog.e(TAG, builder.toString());
}
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b83aa4fb4d86..6328cb60cf73 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -493,6 +493,8 @@ public final class ActiveServices {
}
ServiceRecord r = res.record;
+ setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, r,
+ allowBackgroundActivityStarts);
if (!mAm.mUserController.exists(r.userId)) {
Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId);
@@ -516,6 +518,21 @@ public final class ActiveServices {
forcedStandby = true;
}
+ if (fgRequired) {
+ if (!r.mAllowStartForeground) {
+ if (!r.mLoggedInfoAllowStartForeground) {
+ Slog.wtf(TAG, "Background started FGS " + r.mInfoAllowStartForeground);
+ r.mLoggedInfoAllowStartForeground = true;
+ }
+ if (mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
+ Slog.w(TAG, "startForegroundService() not allowed due to "
+ + " mAllowStartForeground false: service "
+ + r.shortInstanceName);
+ forcedStandby = true;
+ }
+ }
+ }
+
// If this is a direct-to-foreground start, make sure it is allowed as per the app op.
boolean forceSilentAbort = false;
if (fgRequired) {
@@ -688,14 +705,10 @@ public final class ActiveServices {
"Not potential delay (user " + r.userId + " not started): " + r);
}
}
-
if (allowBackgroundActivityStarts) {
r.allowBgActivityStartsOnServiceStart();
}
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
-
- setFgsRestrictionLocked(callingPackage, callingPid,
- callingUid, service, r, allowBackgroundActivityStarts);
return cmp;
}
@@ -1422,8 +1435,8 @@ public final class ActiveServices {
if (mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
Slog.w(TAG,
"Service.startForeground() not allowed due to "
- + " mAllowStartForeground false: service "
- + r.shortInstanceName);
+ + "mAllowStartForeground false: service "
+ + r.shortInstanceName);
updateServiceForegroundLocked(r.app, true);
ignoreForeground = true;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f250647d7711..3e600b793385 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -98,7 +98,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
@@ -146,7 +145,6 @@ import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.StackInfo;
import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerProto;
import android.app.ActivityThread;
import android.app.AppGlobals;
import android.app.AppOpsManager;
@@ -176,7 +174,6 @@ import android.app.PendingIntent;
import android.app.ProcessMemoryState;
import android.app.ProfilerInfo;
import android.app.WaitResult;
-import android.app.backup.BackupManager;
import android.app.backup.BackupManager.OperationType;
import android.app.backup.IBackupManager;
import android.app.usage.UsageEvents;
@@ -349,7 +346,6 @@ import com.android.server.SystemServiceManager;
import com.android.server.ThreadPriorityBooster;
import com.android.server.UserspaceRebootLogger;
import com.android.server.Watchdog;
-import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
import com.android.server.appop.AppOpsService;
import com.android.server.compat.PlatformCompat;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
@@ -490,9 +486,6 @@ public class ActivityManagerService extends IActivityManager.Stub
// as one line, but close enough for now.
static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
- /** If a UID observer takes more than this long, send a WTF. */
- private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
-
// Necessary ApplicationInfo flags to mark an app as persistent
static final int PERSISTENT_MASK =
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
@@ -644,9 +637,6 @@ public class ActivityManagerService extends IActivityManager.Stub
@VisibleForTesting
long mWaitForNetworkTimeoutMs;
- /** Total # of UID change events dispatched, shown in dumpsys. */
- int mUidChangeDispatchCount;
-
/**
* Uids of apps with current active camera sessions. Access synchronized on
* the IntArray instance itself, and no other locks must be acquired while that
@@ -1014,12 +1004,6 @@ public class ActivityManagerService extends IActivityManager.Stub
};
/**
- * This is for verifying the UID report flow.
- */
- static final boolean VALIDATE_UID_STATES = true;
- final ActiveUids mValidateUids = new ActiveUids(this, false /* postChangesToAtm */);
-
- /**
* Fingerprints (hashCode()) of stack traces that we've
* already logged DropBox entries for. Guarded by itself. If
* something (rogue user app) forces this over
@@ -1399,69 +1383,6 @@ public class ActivityManagerService extends IActivityManager.Stub
int foregroundServiceTypes;
}
- static final class UidObserverRegistration {
- final int uid;
- final String pkg;
- final int which;
- final int cutpoint;
-
- /**
- * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
- * We show it in dumpsys.
- */
- int mSlowDispatchCount;
-
- /** Max time it took for each dispatch. */
- int mMaxDispatchTime;
-
- final SparseIntArray lastProcStates;
-
- // Please keep the enum lists in sync
- private static int[] ORIG_ENUMS = new int[]{
- ActivityManager.UID_OBSERVER_IDLE,
- ActivityManager.UID_OBSERVER_ACTIVE,
- ActivityManager.UID_OBSERVER_GONE,
- ActivityManager.UID_OBSERVER_PROCSTATE,
- };
- private static int[] PROTO_ENUMS = new int[]{
- ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
- ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
- ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
- ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
- };
-
- UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
- uid = _uid;
- pkg = _pkg;
- which = _which;
- cutpoint = _cutpoint;
- if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
- lastProcStates = new SparseIntArray();
- } else {
- lastProcStates = null;
- }
- }
-
- void dumpDebug(ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
- proto.write(UidObserverRegistrationProto.UID, uid);
- proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
- ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
- which, ORIG_ENUMS, PROTO_ENUMS);
- proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
- if (lastProcStates != null) {
- final int NI = lastProcStates.size();
- for (int i=0; i<NI; i++) {
- final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
- proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i));
- proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i));
- proto.end(pToken);
- }
- }
- proto.end(token);
- }
- }
-
// TODO: Move below 4 members and code to ProcessList
final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
@@ -1469,12 +1390,6 @@ public class ActivityManagerService extends IActivityManager.Stub
final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
- final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
- UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
-
- final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
- final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
-
OomAdjObserver mCurOomAdjObserver;
int mCurOomAdjUid;
@@ -1525,6 +1440,8 @@ public class ActivityManagerService extends IActivityManager.Stub
public final ActivityManagerInternal mInternal;
final ActivityThread mSystemThread;
+ final UidObserverController mUidObserverController;
+
private final class AppDeathRecipient implements IBinder.DeathRecipient {
final ProcessRecord mApp;
final int mPid;
@@ -1570,7 +1487,6 @@ public class ActivityManagerService extends IActivityManager.Stub
static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
static final int ABORT_DUMPHEAP_MSG = 51;
- static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
static final int IDLE_UIDS_MSG = 58;
@@ -1699,17 +1615,14 @@ public class ActivityManagerService extends IActivityManager.Stub
break;
}
case DISPATCH_PROCESS_DIED_UI_MSG: {
+ if (false) { // DO NOT SUBMIT WITH TRUE
+ maybeTriggerWatchdog();
+ }
final int pid = msg.arg1;
final int uid = msg.arg2;
dispatchProcessDied(pid, uid);
break;
}
- case DISPATCH_UIDS_CHANGED_UI_MSG: {
- if (false) { // DO NOT SUBMIT WITH TRUE
- maybeTriggerWatchdog();
- }
- dispatchUidsChanged();
- } break;
case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
dispatchOomAdjObserver((String) msg.obj);
} break;
@@ -1795,12 +1708,10 @@ public class ActivityManagerService extends IActivityManager.Stub
}
} break;
case CHECK_EXCESSIVE_POWER_USE_MSG: {
- synchronized (ActivityManagerService.this) {
- checkExcessivePowerUsageLocked();
- removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
- Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
- sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
- }
+ checkExcessivePowerUsage();
+ removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
+ Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
+ sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
} break;
case REPORT_MEM_USAGE_MSG: {
final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
@@ -2511,6 +2422,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mConstants = hasHandlerThread
? new ActivityManagerConstants(mContext, this, mHandler) : null;
final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */);
+ mUidObserverController = new UidObserverController(this);
mPlatformCompat = null;
mProcessList = injector.getProcessList(this);
mProcessList.init(this, activeUids, mPlatformCompat);
@@ -2606,6 +2518,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mCpHelper = new ContentProviderHelper(this, true);
mPackageWatchdog = PackageWatchdog.getInstance(mUiContext);
mAppErrors = new AppErrors(mUiContext, this, mPackageWatchdog);
+ mUidObserverController = new UidObserverController(this);
final File systemDir = SystemServiceManager.ensureSystemDir();
@@ -3422,153 +3335,6 @@ public class ActivityManagerService extends IActivityManager.Stub
mProcessObservers.finishBroadcast();
}
- @VisibleForTesting
- void dispatchUidsChanged() {
- int N;
- synchronized (this) {
- N = mPendingUidChanges.size();
- if (mActiveUidChanges.length < N) {
- mActiveUidChanges = new UidRecord.ChangeItem[N];
- }
- for (int i=0; i<N; i++) {
- final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
- mActiveUidChanges[i] = change;
- if (change.uidRecord != null) {
- change.uidRecord.pendingChange = null;
- change.uidRecord = null;
- }
- }
- mPendingUidChanges.clear();
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "*** Delivering " + N + " uid changes");
- }
-
- mUidChangeDispatchCount += N;
- int i = mUidObservers.beginBroadcast();
- while (i > 0) {
- i--;
- dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
- (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
- }
- mUidObservers.finishBroadcast();
-
- if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
- for (int j = 0; j < N; ++j) {
- final UidRecord.ChangeItem item = mActiveUidChanges[j];
- if ((item.change & UidRecord.CHANGE_GONE) != 0) {
- mValidateUids.remove(item.uid);
- } else {
- UidRecord validateUid = mValidateUids.get(item.uid);
- if (validateUid == null) {
- validateUid = new UidRecord(item.uid);
- mValidateUids.put(item.uid, validateUid);
- }
- if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
- validateUid.idle = true;
- } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
- validateUid.idle = false;
- }
- validateUid.setCurProcState(validateUid.setProcState = item.processState);
- validateUid.curCapability = validateUid.setCapability = item.capability;
- validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
- }
- }
- }
-
- synchronized (this) {
- for (int j = 0; j < N; j++) {
- mAvailUidChanges.add(mActiveUidChanges[j]);
- }
- }
- }
-
- private void dispatchUidsChangedForObserver(IUidObserver observer,
- UidObserverRegistration reg, int changesSize) {
- if (observer == null) {
- return;
- }
- try {
- for (int j = 0; j < changesSize; j++) {
- UidRecord.ChangeItem item = mActiveUidChanges[j];
- final int change = item.change;
- if (change == UidRecord.CHANGE_PROCSTATE &&
- (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
- // No-op common case: no significant change, the observer is not
- // interested in all proc state changes.
- continue;
- }
- final long start = SystemClock.uptimeMillis();
- if ((change & UidRecord.CHANGE_IDLE) != 0) {
- if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "UID idle uid=" + item.uid);
- observer.onUidIdle(item.uid, item.ephemeral);
- }
- } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
- if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "UID active uid=" + item.uid);
- observer.onUidActive(item.uid);
- }
- }
- if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
- if ((change & UidRecord.CHANGE_CACHED) != 0) {
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "UID cached uid=" + item.uid);
- observer.onUidCachedChanged(item.uid, true);
- } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "UID active uid=" + item.uid);
- observer.onUidCachedChanged(item.uid, false);
- }
- }
- if ((change & UidRecord.CHANGE_GONE) != 0) {
- if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "UID gone uid=" + item.uid);
- observer.onUidGone(item.uid, item.ephemeral);
- }
- if (reg.lastProcStates != null) {
- reg.lastProcStates.delete(item.uid);
- }
- } else {
- if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "UID CHANGED uid=" + item.uid
- + ": " + item.processState + ": " + item.capability);
- boolean doReport = true;
- if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
- final int lastState = reg.lastProcStates.get(item.uid,
- ActivityManager.PROCESS_STATE_UNKNOWN);
- if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
- final boolean lastAboveCut = lastState <= reg.cutpoint;
- final boolean newAboveCut = item.processState <= reg.cutpoint;
- doReport = lastAboveCut != newAboveCut;
- } else {
- doReport = item.processState != PROCESS_STATE_NONEXISTENT;
- }
- }
- if (doReport) {
- if (reg.lastProcStates != null) {
- reg.lastProcStates.put(item.uid, item.processState);
- }
- observer.onUidStateChanged(item.uid, item.processState,
- item.procStateSeq, item.capability);
- }
- }
- }
- final int duration = (int) (SystemClock.uptimeMillis() - start);
- if (reg.mMaxDispatchTime < duration) {
- reg.mMaxDispatchTime = duration;
- }
- if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
- reg.mSlowDispatchCount++;
- }
- }
- } catch (RemoteException e) {
- }
- }
-
void dispatchOomAdjObserver(String msg) {
OomAdjObserver observer;
synchronized (this) {
@@ -4609,10 +4375,12 @@ public class ActivityManagerService extends IActivityManager.Stub
proc.lastMemInfoTime = SystemClock.uptimeMillis();
if (proc.thread != null && proc.setAdj == oomAdj) {
// Record this for posterity if the process has been stable.
- proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
- infos[i].getTotalUss(), infos[i].getTotalRss(), false,
- ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime - startTime,
- proc.pkgList.mPkgList);
+ synchronized (mProcessStats.mLock) {
+ proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
+ infos[i].getTotalUss(), infos[i].getTotalRss(), false,
+ ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime - startTime,
+ proc.pkgList.mPkgList);
+ }
for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_MEMORY_STAT_REPORTED,
@@ -4669,8 +4437,11 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (this) {
if (proc.thread != null && proc.setAdj == oomAdj) {
// Record this for posterity if the process has been stable.
- proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
- ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList.mPkgList);
+ synchronized (mProcessStats.mLock) {
+ proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false,
+ ProcessStats.ADD_PSS_EXTERNAL, endTime - startTime,
+ proc.pkgList.mPkgList);
+ }
for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_MEMORY_STAT_REPORTED,
@@ -7500,15 +7271,15 @@ public class ActivityManagerService extends IActivityManager.Stub
"registerUidObserver");
}
synchronized (this) {
- mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
- callingPackage, which, cutpoint));
+ mUidObserverController.register(observer, which, cutpoint, callingPackage,
+ Binder.getCallingUid());
}
}
@Override
public void unregisterUidObserver(IUidObserver observer) {
synchronized (this) {
- mUidObservers.unregister(observer);
+ mUidObserverController.unregister(observer);
}
}
@@ -10127,9 +9898,9 @@ public class ActivityManagerService extends IActivityManager.Stub
}
if (dumpAll) {
- if (mValidateUids.size() > 0) {
- if (dumpUids(pw, dumpPackage, dumpAppId, mValidateUids, "UID validation:",
- needSep)) {
+ if (mUidObserverController.mValidateUids.size() > 0) {
+ if (dumpUids(pw, dumpPackage, dumpAppId, mUidObserverController.mValidateUids,
+ "UID validation:", needSep)) {
needSep = true;
}
}
@@ -10261,45 +10032,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
if (dumpAll) {
- final int NI = mUidObservers.getRegisteredCallbackCount();
- boolean printed = false;
- for (int i=0; i<NI; i++) {
- final UidObserverRegistration reg = (UidObserverRegistration)
- mUidObservers.getRegisteredCallbackCookie(i);
- if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
- if (!printed) {
- pw.println(" mUidObservers:");
- printed = true;
- }
- pw.print(" "); UserHandle.formatUid(pw, reg.uid);
- pw.print(" "); pw.print(reg.pkg);
- final IUidObserver observer = mUidObservers.getRegisteredCallbackItem(i);
- pw.print(" "); pw.print(observer.getClass().getTypeName()); pw.print(":");
- if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
- pw.print(" IDLE");
- }
- if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
- pw.print(" ACT" );
- }
- if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
- pw.print(" GONE");
- }
- if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
- pw.print(" STATE");
- pw.print(" (cut="); pw.print(reg.cutpoint);
- pw.print(")");
- }
- pw.println();
- if (reg.lastProcStates != null) {
- final int NJ = reg.lastProcStates.size();
- for (int j=0; j<NJ; j++) {
- pw.print(" Last ");
- UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
- pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
- }
- }
- }
- }
+ mUidObserverController.dump(pw, dumpPackage);
+
pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
pw.println(" mDeviceIdleExceptIdleWhitelist="
+ Arrays.toString(mDeviceIdleExceptIdleWhitelist));
@@ -10427,25 +10161,6 @@ public class ActivityManagerService extends IActivityManager.Stub
pw.print(" mLowRamSinceLastIdle=");
TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
pw.println();
- pw.println();
- pw.print(" mUidChangeDispatchCount=");
- pw.print(mUidChangeDispatchCount);
- pw.println();
-
- pw.println(" Slow UID dispatches:");
- final int N = mUidObservers.beginBroadcast();
- for (int i = 0; i < N; i++) {
- UidObserverRegistration r =
- (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
- pw.print(" ");
- pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
- pw.print(": ");
- pw.print(r.mSlowDispatchCount);
- pw.print(" / Max ");
- pw.print(r.mMaxDispatchTime);
- pw.println("ms");
- }
- mUidObservers.finishBroadcast();
pw.println();
pw.println(" ServiceManager statistics:");
@@ -10513,8 +10228,8 @@ public class ActivityManagerService extends IActivityManager.Stub
uidRec.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.ACTIVE_UIDS);
}
- for (int i = 0; i < mValidateUids.size(); i++) {
- UidRecord uidRec = mValidateUids.valueAt(i);
+ for (int i = 0; i < mUidObserverController.mValidateUids.size(); i++) {
+ UidRecord uidRec = mUidObserverController.mValidateUids.valueAt(i);
if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
continue;
}
@@ -10599,14 +10314,7 @@ public class ActivityManagerService extends IActivityManager.Stub
ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
}
- final int NI = mUidObservers.getRegisteredCallbackCount();
- for (int i=0; i<NI; i++) {
- final UidObserverRegistration reg = (UidObserverRegistration)
- mUidObservers.getRegisteredCallbackCookie(i);
- if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
- reg.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
- }
- }
+ mUidObserverController.dumpDebug(proto, dumpPackage);
for (int v : mDeviceIdleWhitelist) {
proto.write(ActivityManagerServiceDumpProcessesProto.DEVICE_IDLE_WHITELIST, v);
@@ -12107,8 +11815,10 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (this) {
if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
// Record this for posterity if the process has been stable.
- r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
- reportType, endTime-startTime, r.pkgList.mPkgList);
+ synchronized (mProcessStats.mLock) {
+ r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
+ reportType, endTime - startTime, r.pkgList.mPkgList);
+ }
for (int ipkg = r.pkgList.size() - 1; ipkg >= 0; ipkg--) {
ProcessStats.ProcessStateHolder holder = r.pkgList.valueAt(ipkg);
FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_MEMORY_STAT_REPORTED,
@@ -12713,8 +12423,10 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (this) {
if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
// Record this for posterity if the process has been stable.
- r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
- reportType, endTime-startTime, r.pkgList.mPkgList);
+ synchronized (mProcessStats.mLock) {
+ r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true,
+ reportType, endTime - startTime, r.pkgList.mPkgList);
+ }
for (int ipkg = r.pkgList.size() - 1; ipkg >= 0; ipkg--) {
ProcessStats.ProcessStateHolder holder = r.pkgList.valueAt(ipkg);
FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_MEMORY_STAT_REPORTED,
@@ -15927,8 +15639,10 @@ public class ActivityManagerService extends IActivityManager.Stub
EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
swapPss * 1024, rss * 1024, statType, procState, pssDuration);
proc.lastPssTime = now;
- proc.baseProcessTracker.addPss(
- pss, uss, rss, true, statType, pssDuration, proc.pkgList.mPkgList);
+ synchronized (mProcessStats.mLock) {
+ proc.baseProcessTracker.addPss(
+ pss, uss, rss, true, statType, pssDuration, proc.pkgList.mPkgList);
+ }
for (int ipkg = proc.pkgList.mPkgList.size() - 1; ipkg >= 0; ipkg--) {
ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
FrameworkStatsLog.write(FrameworkStatsLog.PROCESS_MEMORY_STAT_REPORTED,
@@ -16230,182 +15944,94 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
- final void checkExcessivePowerUsageLocked() {
+ private void checkExcessivePowerUsage() {
updateCpuStatsNow();
- BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
- boolean doCpuKills = true;
- if (mLastPowerCheckUptime == 0) {
- doCpuKills = false;
- }
- final long curUptime = SystemClock.uptimeMillis();
- final long uptimeSince = curUptime - mLastPowerCheckUptime;
- mLastPowerCheckUptime = curUptime;
- int i = mProcessList.mLruProcesses.size();
- while (i > 0) {
- i--;
- ProcessRecord app = mProcessList.mLruProcesses.get(i);
- if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
- if (app.lastCpuTime <= 0) {
- continue;
- }
- long cputimeUsed = app.curCpuTime - app.lastCpuTime;
- if (DEBUG_POWER) {
- StringBuilder sb = new StringBuilder(128);
- sb.append("CPU for ");
- app.toShortString(sb);
- sb.append(": over ");
- TimeUtils.formatDuration(uptimeSince, sb);
- sb.append(" used ");
- TimeUtils.formatDuration(cputimeUsed, sb);
- sb.append(" (");
- sb.append((cputimeUsed*100)/uptimeSince);
- sb.append("%)");
- Slog.i(TAG_POWER, sb.toString());
- }
- // If the process has used too much CPU over the last duration, the
- // user probably doesn't want this, so kill!
- if (doCpuKills && uptimeSince > 0) {
- // What is the limit for this process?
- int cpuLimit;
- long checkDur = curUptime - app.getWhenUnimportant();
- if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
- cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
- } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
- || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
- cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
- } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
- cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
- } else {
- cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
+ synchronized (this) {
+ BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
+ boolean doCpuKills = true;
+ if (mLastPowerCheckUptime == 0) {
+ doCpuKills = false;
+ }
+ final long curUptime = SystemClock.uptimeMillis();
+ final long uptimeSince = curUptime - mLastPowerCheckUptime;
+ mLastPowerCheckUptime = curUptime;
+ int i = mProcessList.mLruProcesses.size();
+ while (i > 0) {
+ i--;
+ ProcessRecord app = mProcessList.mLruProcesses.get(i);
+ if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
+ if (app.lastCpuTime <= 0) {
+ continue;
+ }
+ long cputimeUsed = app.curCpuTime - app.lastCpuTime;
+ if (DEBUG_POWER) {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("CPU for ");
+ app.toShortString(sb);
+ sb.append(": over ");
+ TimeUtils.formatDuration(uptimeSince, sb);
+ sb.append(" used ");
+ TimeUtils.formatDuration(cputimeUsed, sb);
+ sb.append(" (");
+ sb.append((cputimeUsed * 100) / uptimeSince);
+ sb.append("%)");
+ Slog.i(TAG_POWER, sb.toString());
}
- if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
- synchronized (stats) {
- stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
- uptimeSince, cputimeUsed);
+ // If the process has used too much CPU over the last duration, the
+ // user probably doesn't want this, so kill!
+ if (doCpuKills && uptimeSince > 0) {
+ // What is the limit for this process?
+ int cpuLimit;
+ long checkDur = curUptime - app.getWhenUnimportant();
+ if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
+ cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
+ } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL * 2)
+ || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
+ cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
+ } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL * 3)) {
+ cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
+ } else {
+ cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
}
- app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
- + " dur=" + checkDur + " limit=" + cpuLimit,
- ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE,
- ApplicationExitInfo.SUBREASON_EXCESSIVE_CPU,
- true);
- app.baseProcessTracker.reportExcessiveCpu(app.pkgList.mPkgList);
- for (int ipkg = app.pkgList.size() - 1; ipkg >= 0; ipkg--) {
- ProcessStats.ProcessStateHolder holder = app.pkgList.valueAt(ipkg);
- FrameworkStatsLog.write(FrameworkStatsLog.EXCESSIVE_CPU_USAGE_REPORTED,
- app.info.uid,
- holder.state.getName(),
- holder.state.getPackage(),
- holder.appVersion);
+ if (((cputimeUsed * 100) / uptimeSince) >= cpuLimit) {
+ synchronized (stats) {
+ stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
+ uptimeSince, cputimeUsed);
+ }
+ app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
+ + " dur=" + checkDur + " limit=" + cpuLimit,
+ ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE,
+ ApplicationExitInfo.SUBREASON_EXCESSIVE_CPU,
+ true);
+ synchronized (mProcessStats.mLock) {
+ app.baseProcessTracker.reportExcessiveCpu(app.pkgList.mPkgList);
+ }
+ for (int ipkg = app.pkgList.size() - 1; ipkg >= 0; ipkg--) {
+ ProcessStats.ProcessStateHolder holder = app.pkgList.valueAt(ipkg);
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.EXCESSIVE_CPU_USAGE_REPORTED,
+ app.info.uid,
+ holder.state.getName(),
+ holder.state.getPackage(),
+ holder.appVersion);
+ }
}
}
+ app.lastCpuTime = app.curCpuTime;
}
- app.lastCpuTime = app.curCpuTime;
- }
- }
- }
-
- private boolean isEphemeralLocked(int uid) {
- String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
- if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
- return false;
- }
- return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
- packages[0]);
- }
-
- @VisibleForTesting
- final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
- final UidRecord.ChangeItem pendingChange;
- if (uidRec == null || uidRec.pendingChange == null) {
- if (mPendingUidChanges.size() == 0) {
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "*** Enqueueing dispatch uid changed!");
- mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
- }
- final int NA = mAvailUidChanges.size();
- if (NA > 0) {
- pendingChange = mAvailUidChanges.remove(NA-1);
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "Retrieving available item: " + pendingChange);
- } else {
- pendingChange = new UidRecord.ChangeItem();
- if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
- "Allocating new item: " + pendingChange);
- }
- if (uidRec != null) {
- uidRec.pendingChange = pendingChange;
- if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
- // If this uid is going away, and we haven't yet reported it is gone,
- // then do so now.
- change |= UidRecord.CHANGE_IDLE;
- }
- } else if (uid < 0) {
- throw new IllegalArgumentException("No UidRecord or uid");
- }
- pendingChange.uidRecord = uidRec;
- pendingChange.uid = uidRec != null ? uidRec.uid : uid;
- mPendingUidChanges.add(pendingChange);
- } else {
- pendingChange = uidRec.pendingChange;
- // If there is no change in idle or active state, then keep whatever was pending.
- if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
- change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
- | UidRecord.CHANGE_ACTIVE));
- }
- // If there is no change in cached or uncached state, then keep whatever was pending.
- if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
- change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
- | UidRecord.CHANGE_UNCACHED));
- }
- // If this is a report of the UID being gone, then we shouldn't keep any previous
- // report of it being active or cached. (That is, a gone uid is never active,
- // and never cached.)
- if ((change & UidRecord.CHANGE_GONE) != 0) {
- change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
- if (!uidRec.idle) {
- // If this uid is going away, and we haven't yet reported it is gone,
- // then do so now.
- change |= UidRecord.CHANGE_IDLE;
- }
- }
- }
- pendingChange.change = change;
- pendingChange.processState = uidRec != null ? uidRec.setProcState : PROCESS_STATE_NONEXISTENT;
- pendingChange.capability = uidRec != null ? uidRec.setCapability : 0;
- pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
- pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
- if (uidRec != null) {
- uidRec.lastReportedChange = change;
- uidRec.updateLastDispatchedProcStateSeq(change);
- }
-
- // Directly update the power manager, since we sit on top of it and it is critical
- // it be kept in sync (so wake locks will be held as soon as appropriate).
- if (mLocalPowerManager != null) {
- // TO DO: dispatch cached/uncached changes here, so we don't need to report
- // all proc state changes.
- if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
- mLocalPowerManager.uidActive(pendingChange.uid);
- }
- if ((change & UidRecord.CHANGE_IDLE) != 0) {
- mLocalPowerManager.uidIdle(pendingChange.uid);
- }
- if ((change & UidRecord.CHANGE_GONE) != 0) {
- mLocalPowerManager.uidGone(pendingChange.uid);
- } else {
- mLocalPowerManager.updateUidProcState(pendingChange.uid,
- pendingChange.processState);
}
}
}
final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
- if (proc.thread != null && proc.baseProcessTracker != null) {
- final int procState = proc.getReportedProcState();
- if (procState != PROCESS_STATE_NONEXISTENT) {
- proc.baseProcessTracker.setState(
- procState, memFactor, now, proc.pkgList.mPkgList);
+ synchronized (mProcessStats.mLock) {
+ if (proc.thread != null && proc.baseProcessTracker != null) {
+ final int procState = proc.getReportedProcState();
+ if (procState != PROCESS_STATE_NONEXISTENT) {
+ proc.baseProcessTracker.setState(
+ procState, memFactor, now, proc.pkgList.mPkgList);
+ }
}
}
}
@@ -16818,7 +16444,7 @@ public class ActivityManagerService extends IActivityManager.Stub
@GuardedBy("this")
final void doStopUidLocked(int uid, final UidRecord uidRec) {
mServices.stopInBackgroundLocked(uid);
- enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
+ mUidObserverController.enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
}
/**
@@ -18479,7 +18105,8 @@ public class ActivityManagerService extends IActivityManager.Stub
Slog.w(TAG_NETWORK, "Total time waited for network rules to get updated: "
+ totalTime + ". Uid: " + callingUid + " procStateSeq: "
+ procStateSeq + " UidRec: " + record
- + " validateUidRec: " + mValidateUids.get(callingUid));
+ + " validateUidRec: "
+ + mUidObserverController.mValidateUids.get(callingUid));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index bf15f1737cfc..bad042cd3a68 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -987,7 +987,7 @@ public final class OomAdjuster {
uidRec.setWhitelist = uidRec.curWhitelist;
uidRec.setIdle = uidRec.idle;
mService.mAtmInternal.onUidProcStateChanged(uidRec.uid, uidRec.setProcState);
- mService.enqueueUidChangeLocked(uidRec, -1, uidChange);
+ mService.mUidObserverController.enqueueUidChangeLocked(uidRec, -1, uidChange);
mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState(),
uidRec.curCapability);
if (uidRec.foregroundServices) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 5721fb7f5128..2e8660e1317a 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2960,7 +2960,8 @@ public final class ProcessList {
// No more processes using this uid, tell clients it is gone.
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
"No more processes in " + uidRecord);
- mService.enqueueUidChangeLocked(uidRecord, -1, UidRecord.CHANGE_GONE);
+ mService.mUidObserverController.enqueueUidChangeLocked(uidRecord, -1,
+ UidRecord.CHANGE_GONE);
EventLogTags.writeAmUidStopped(uid);
mActiveUids.remove(uid);
mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT,
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index e3e13391a8b0..14bc6cbed7d7 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1079,8 +1079,8 @@ class ProcessRecord implements WindowProcessListener {
*/
public void resetPackageList(ProcessStatsService tracker) {
final int N = pkgList.size();
- if (baseProcessTracker != null) {
- synchronized (tracker.mLock) {
+ synchronized (tracker.mLock) {
+ if (baseProcessTracker != null) {
long now = SystemClock.uptimeMillis();
baseProcessTracker.setState(ProcessStats.STATE_NOTHING,
tracker.getMemFactorLocked(), now, pkgList.mPkgList);
@@ -1108,10 +1108,11 @@ class ProcessRecord implements WindowProcessListener {
holder.state.makeActive();
}
}
+ } else if (N != 1) {
+ pkgList.clear();
+ pkgList.put(info.packageName,
+ new ProcessStats.ProcessStateHolder(info.longVersionCode));
}
- } else if (N != 1) {
- pkgList.clear();
- pkgList.put(info.packageName, new ProcessStats.ProcessStateHolder(info.longVersionCode));
}
}
diff --git a/services/core/java/com/android/server/am/UidObserverController.java b/services/core/java/com/android/server/am/UidObserverController.java
new file mode 100644
index 000000000000..4c4dd8b8defa
--- /dev/null
+++ b/services/core/java/com/android/server/am/UidObserverController.java
@@ -0,0 +1,460 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.am;
+
+import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
+import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
+
+import android.app.ActivityManager;
+import android.app.ActivityManagerProto;
+import android.app.IUidObserver;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.Slog;
+import android.util.SparseIntArray;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+public class UidObserverController {
+ private final ActivityManagerService mService;
+ final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
+
+ UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
+ final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
+ final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
+
+ /** Total # of UID change events dispatched, shown in dumpsys. */
+ int mUidChangeDispatchCount;
+
+ /** If a UID observer takes more than this long, send a WTF. */
+ private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
+
+ /**
+ * This is for verifying the UID report flow.
+ */
+ static final boolean VALIDATE_UID_STATES = true;
+ final ActiveUids mValidateUids;
+
+ UidObserverController(ActivityManagerService service) {
+ mService = service;
+ mValidateUids = new ActiveUids(mService, false /* postChangesToAtm */);
+ }
+
+ @GuardedBy("mService")
+ void register(IUidObserver observer, int which, int cutpoint, String callingPackage,
+ int callingUid) {
+ mUidObservers.register(observer, new UidObserverRegistration(callingUid,
+ callingPackage, which, cutpoint));
+ }
+
+ @GuardedBy("mService")
+ void unregister(IUidObserver observer) {
+ mUidObservers.unregister(observer);
+ }
+
+ @GuardedBy("mService")
+ final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
+ final UidRecord.ChangeItem pendingChange;
+ if (uidRec == null || uidRec.pendingChange == null) {
+ if (mPendingUidChanges.size() == 0) {
+ if (DEBUG_UID_OBSERVERS) {
+ Slog.i(TAG_UID_OBSERVERS, "*** Enqueueing dispatch uid changed!");
+ }
+ mService.mUiHandler.post(this::dispatchUidsChanged);
+ }
+ final int NA = mAvailUidChanges.size();
+ if (NA > 0) {
+ pendingChange = mAvailUidChanges.remove(NA-1);
+ if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+ "Retrieving available item: " + pendingChange);
+ } else {
+ pendingChange = new UidRecord.ChangeItem();
+ if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+ "Allocating new item: " + pendingChange);
+ }
+ if (uidRec != null) {
+ uidRec.pendingChange = pendingChange;
+ if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
+ // If this uid is going away, and we haven't yet reported it is gone,
+ // then do so now.
+ change |= UidRecord.CHANGE_IDLE;
+ }
+ } else if (uid < 0) {
+ throw new IllegalArgumentException("No UidRecord or uid");
+ }
+ pendingChange.uidRecord = uidRec;
+ pendingChange.uid = uidRec != null ? uidRec.uid : uid;
+ mPendingUidChanges.add(pendingChange);
+ } else {
+ pendingChange = uidRec.pendingChange;
+ // If there is no change in idle or active state, then keep whatever was pending.
+ if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
+ change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
+ | UidRecord.CHANGE_ACTIVE));
+ }
+ // If there is no change in cached or uncached state, then keep whatever was pending.
+ if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
+ change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
+ | UidRecord.CHANGE_UNCACHED));
+ }
+ // If this is a report of the UID being gone, then we shouldn't keep any previous
+ // report of it being active or cached. (That is, a gone uid is never active,
+ // and never cached.)
+ if ((change & UidRecord.CHANGE_GONE) != 0) {
+ change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
+ if (!uidRec.idle) {
+ // If this uid is going away, and we haven't yet reported it is gone,
+ // then do so now.
+ change |= UidRecord.CHANGE_IDLE;
+ }
+ }
+ }
+ pendingChange.change = change;
+ pendingChange.processState = uidRec != null ? uidRec.setProcState : PROCESS_STATE_NONEXISTENT;
+ pendingChange.capability = uidRec != null ? uidRec.setCapability : 0;
+ pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
+ pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
+ if (uidRec != null) {
+ uidRec.lastReportedChange = change;
+ uidRec.updateLastDispatchedProcStateSeq(change);
+ }
+
+ // Directly update the power manager, since we sit on top of it and it is critical
+ // it be kept in sync (so wake locks will be held as soon as appropriate).
+ if (mService.mLocalPowerManager != null) {
+ // TO DO: dispatch cached/uncached changes here, so we don't need to report
+ // all proc state changes.
+ if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
+ mService.mLocalPowerManager.uidActive(pendingChange.uid);
+ }
+ if ((change & UidRecord.CHANGE_IDLE) != 0) {
+ mService.mLocalPowerManager.uidIdle(pendingChange.uid);
+ }
+ if ((change & UidRecord.CHANGE_GONE) != 0) {
+ mService.mLocalPowerManager.uidGone(pendingChange.uid);
+ } else {
+ mService.mLocalPowerManager.updateUidProcState(pendingChange.uid,
+ pendingChange.processState);
+ }
+ }
+ }
+
+ @VisibleForTesting
+ void dispatchUidsChanged() {
+ int N;
+ synchronized (mService) {
+ N = mPendingUidChanges.size();
+ if (mActiveUidChanges.length < N) {
+ mActiveUidChanges = new UidRecord.ChangeItem[N];
+ }
+ for (int i=0; i<N; i++) {
+ final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
+ mActiveUidChanges[i] = change;
+ if (change.uidRecord != null) {
+ change.uidRecord.pendingChange = null;
+ change.uidRecord = null;
+ }
+ }
+ mPendingUidChanges.clear();
+ if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+ "*** Delivering " + N + " uid changes");
+ }
+
+ mUidChangeDispatchCount += N;
+ int i = mUidObservers.beginBroadcast();
+ while (i > 0) {
+ i--;
+ dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
+ (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
+ }
+ mUidObservers.finishBroadcast();
+
+ if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
+ for (int j = 0; j < N; ++j) {
+ final UidRecord.ChangeItem item = mActiveUidChanges[j];
+ if ((item.change & UidRecord.CHANGE_GONE) != 0) {
+ mValidateUids.remove(item.uid);
+ } else {
+ UidRecord validateUid = mValidateUids.get(item.uid);
+ if (validateUid == null) {
+ validateUid = new UidRecord(item.uid);
+ mValidateUids.put(item.uid, validateUid);
+ }
+ if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
+ validateUid.idle = true;
+ } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
+ validateUid.idle = false;
+ }
+ validateUid.setCurProcState(validateUid.setProcState = item.processState);
+ validateUid.curCapability = validateUid.setCapability = item.capability;
+ validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
+ }
+ }
+ }
+
+ synchronized (mService) {
+ for (int j = 0; j < N; j++) {
+ mAvailUidChanges.add(mActiveUidChanges[j]);
+ }
+ }
+ }
+
+ private void dispatchUidsChangedForObserver(IUidObserver observer,
+ UidObserverRegistration reg, int changesSize) {
+ if (observer == null) {
+ return;
+ }
+ try {
+ for (int j = 0; j < changesSize; j++) {
+ UidRecord.ChangeItem item = mActiveUidChanges[j];
+ final int change = item.change;
+ if (change == UidRecord.CHANGE_PROCSTATE &&
+ (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
+ // No-op common case: no significant change, the observer is not
+ // interested in all proc state changes.
+ continue;
+ }
+ final long start = SystemClock.uptimeMillis();
+ if ((change & UidRecord.CHANGE_IDLE) != 0) {
+ if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
+ if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+ "UID idle uid=" + item.uid);
+ observer.onUidIdle(item.uid, item.ephemeral);
+ }
+ } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
+ if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
+ if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+ "UID active uid=" + item.uid);
+ observer.onUidActive(item.uid);
+ }
+ }
+ if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
+ if ((change & UidRecord.CHANGE_CACHED) != 0) {
+ if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+ "UID cached uid=" + item.uid);
+ observer.onUidCachedChanged(item.uid, true);
+ } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
+ if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+ "UID active uid=" + item.uid);
+ observer.onUidCachedChanged(item.uid, false);
+ }
+ }
+ if ((change & UidRecord.CHANGE_GONE) != 0) {
+ if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
+ if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+ "UID gone uid=" + item.uid);
+ observer.onUidGone(item.uid, item.ephemeral);
+ }
+ if (reg.lastProcStates != null) {
+ reg.lastProcStates.delete(item.uid);
+ }
+ } else {
+ if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
+ if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+ "UID CHANGED uid=" + item.uid
+ + ": " + item.processState + ": " + item.capability);
+ boolean doReport = true;
+ if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
+ final int lastState = reg.lastProcStates.get(item.uid,
+ ActivityManager.PROCESS_STATE_UNKNOWN);
+ if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
+ final boolean lastAboveCut = lastState <= reg.cutpoint;
+ final boolean newAboveCut = item.processState <= reg.cutpoint;
+ doReport = lastAboveCut != newAboveCut;
+ } else {
+ doReport = item.processState != PROCESS_STATE_NONEXISTENT;
+ }
+ }
+ if (doReport) {
+ if (reg.lastProcStates != null) {
+ reg.lastProcStates.put(item.uid, item.processState);
+ }
+ observer.onUidStateChanged(item.uid, item.processState,
+ item.procStateSeq, item.capability);
+ }
+ }
+ }
+ final int duration = (int) (SystemClock.uptimeMillis() - start);
+ if (reg.mMaxDispatchTime < duration) {
+ reg.mMaxDispatchTime = duration;
+ }
+ if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
+ reg.mSlowDispatchCount++;
+ }
+ }
+ } catch (RemoteException e) {
+ }
+ }
+
+ private boolean isEphemeralLocked(int uid) {
+ String packages[] = mService.mContext.getPackageManager().getPackagesForUid(uid);
+ if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
+ return false;
+ }
+ return mService.getPackageManagerInternalLocked().isPackageEphemeral(
+ UserHandle.getUserId(uid), packages[0]);
+ }
+
+ @GuardedBy("mService")
+ void dump(PrintWriter pw, String dumpPackage) {
+ final int NI = mUidObservers.getRegisteredCallbackCount();
+ boolean printed = false;
+ for (int i=0; i<NI; i++) {
+ final UidObserverRegistration reg = (UidObserverRegistration)
+ mUidObservers.getRegisteredCallbackCookie(i);
+ if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
+ if (!printed) {
+ pw.println(" mUidObservers:");
+ printed = true;
+ }
+ pw.print(" "); UserHandle.formatUid(pw, reg.uid);
+ pw.print(" "); pw.print(reg.pkg);
+ final IUidObserver observer = mUidObservers.getRegisteredCallbackItem(i);
+ pw.print(" "); pw.print(observer.getClass().getTypeName()); pw.print(":");
+ if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
+ pw.print(" IDLE");
+ }
+ if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
+ pw.print(" ACT" );
+ }
+ if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
+ pw.print(" GONE");
+ }
+ if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
+ pw.print(" STATE");
+ pw.print(" (cut="); pw.print(reg.cutpoint);
+ pw.print(")");
+ }
+ pw.println();
+ if (reg.lastProcStates != null) {
+ final int NJ = reg.lastProcStates.size();
+ for (int j=0; j<NJ; j++) {
+ pw.print(" Last ");
+ UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
+ pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
+ }
+ }
+ }
+ }
+
+ pw.println();
+ pw.print(" mUidChangeDispatchCount=");
+ pw.print(mUidChangeDispatchCount);
+ pw.println();
+ pw.println(" Slow UID dispatches:");
+ final int N = mUidObservers.beginBroadcast();
+ for (int i = 0; i < N; i++) {
+ UidObserverRegistration r =
+ (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
+ pw.print(" ");
+ pw.print(mUidObservers.getBroadcastItem(i).getClass().getTypeName());
+ pw.print(": ");
+ pw.print(r.mSlowDispatchCount);
+ pw.print(" / Max ");
+ pw.print(r.mMaxDispatchTime);
+ pw.println("ms");
+ }
+ mUidObservers.finishBroadcast();
+ }
+
+ @GuardedBy("mService")
+ void dumpDebug(ProtoOutputStream proto, String dumpPackage) {
+ final int NI = mUidObservers.getRegisteredCallbackCount();
+ for (int i=0; i<NI; i++) {
+ final UidObserverRegistration reg = (UidObserverRegistration)
+ mUidObservers.getRegisteredCallbackCookie(i);
+ if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
+ reg.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
+ }
+ }
+ }
+
+ static final class UidObserverRegistration {
+ final int uid;
+ final String pkg;
+ final int which;
+ final int cutpoint;
+
+ /**
+ * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
+ * We show it in dumpsys.
+ */
+ int mSlowDispatchCount;
+
+ /** Max time it took for each dispatch. */
+ int mMaxDispatchTime;
+
+ final SparseIntArray lastProcStates;
+
+ // Please keep the enum lists in sync
+ private static int[] ORIG_ENUMS = new int[]{
+ ActivityManager.UID_OBSERVER_IDLE,
+ ActivityManager.UID_OBSERVER_ACTIVE,
+ ActivityManager.UID_OBSERVER_GONE,
+ ActivityManager.UID_OBSERVER_PROCSTATE,
+ };
+ private static int[] PROTO_ENUMS = new int[]{
+ ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
+ ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
+ ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
+ ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
+ };
+
+ UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
+ uid = _uid;
+ pkg = _pkg;
+ which = _which;
+ cutpoint = _cutpoint;
+ if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
+ lastProcStates = new SparseIntArray();
+ } else {
+ lastProcStates = null;
+ }
+ }
+
+ void dumpDebug(ProtoOutputStream proto, long fieldId) {
+ final long token = proto.start(fieldId);
+ proto.write(UidObserverRegistrationProto.UID, uid);
+ proto.write(UidObserverRegistrationProto.PACKAGE, pkg);
+ ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
+ which, ORIG_ENUMS, PROTO_ENUMS);
+ proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint);
+ if (lastProcStates != null) {
+ final int NI = lastProcStates.size();
+ for (int i=0; i<NI; i++) {
+ final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
+ proto.write(UidObserverRegistrationProto.ProcState.UID,
+ lastProcStates.keyAt(i));
+ proto.write(UidObserverRegistrationProto.ProcState.STATE,
+ lastProcStates.valueAt(i));
+ proto.end(pToken);
+ }
+ }
+ proto.end(token);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 7420e0a6e828..83bf28e2d3ba 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -988,6 +988,8 @@ class UserController implements Handler.Callback {
final ArrayList<IStopUserCallback> stopCallbacks;
final ArrayList<KeyEvictedCallback> keyEvictedCallbacks;
int userIdToLock = userId;
+ // Must get a reference to UserInfo before it's removed
+ final UserInfo userInfo = getUserInfo(userId);
synchronized (mLock) {
stopCallbacks = new ArrayList<>(uss.mStopCallbacks);
keyEvictedCallbacks = new ArrayList<>(uss.mKeyEvictedCallbacks);
@@ -1030,8 +1032,8 @@ class UserController implements Handler.Callback {
if (stopped) {
mInjector.systemServiceManagerCleanupUser(userId);
mInjector.stackSupervisorRemoveUser(userId);
+
// Remove the user if it is ephemeral.
- UserInfo userInfo = getUserInfo(userId);
if (userInfo.isEphemeral() && !userInfo.preCreated) {
mInjector.getUserManager().removeUserEvenWhenDisallowed(userId);
}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index ee441bf06d04..dfe8af155a04 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -6222,7 +6222,9 @@ public class AppOpsService extends IAppOpsService.Stub {
int[] users;
if (userId == UserHandle.USER_ALL) {
- List<UserInfo> liveUsers = UserManager.get(mContext).getUsers(false);
+ // TODO(b/157921703): this call is returning all users, not just live ones - we
+ // need to either fix the method called, or rename the variable
+ List<UserInfo> liveUsers = UserManager.get(mContext).getUsers();
users = new int[liveUsers.size()];
for (int i = 0; i < liveUsers.size(); i++) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 2bbbbf1664d1..06ef58f8cc61 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -28,7 +28,7 @@ import android.media.AudioDeviceAttributes;
import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
-import android.media.IStrategyPreferredDeviceDispatcher;
+import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.MediaMetrics;
import android.os.Binder;
import android.os.Handler;
@@ -47,6 +47,7 @@ import com.android.internal.annotations.GuardedBy;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -526,23 +527,23 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
- /*package*/ int setPreferredDeviceForStrategySync(int strategy,
- @NonNull AudioDeviceAttributes device) {
- return mDeviceInventory.setPreferredDeviceForStrategySync(strategy, device);
+ /*package*/ int setPreferredDevicesForStrategySync(int strategy,
+ @NonNull List<AudioDeviceAttributes> devices) {
+ return mDeviceInventory.setPreferredDevicesForStrategySync(strategy, devices);
}
- /*package*/ int removePreferredDeviceForStrategySync(int strategy) {
- return mDeviceInventory.removePreferredDeviceForStrategySync(strategy);
+ /*package*/ int removePreferredDevicesForStrategySync(int strategy) {
+ return mDeviceInventory.removePreferredDevicesForStrategySync(strategy);
}
- /*package*/ void registerStrategyPreferredDeviceDispatcher(
- @NonNull IStrategyPreferredDeviceDispatcher dispatcher) {
- mDeviceInventory.registerStrategyPreferredDeviceDispatcher(dispatcher);
+ /*package*/ void registerStrategyPreferredDevicesDispatcher(
+ @NonNull IStrategyPreferredDevicesDispatcher dispatcher) {
+ mDeviceInventory.registerStrategyPreferredDevicesDispatcher(dispatcher);
}
- /*package*/ void unregisterStrategyPreferredDeviceDispatcher(
- @NonNull IStrategyPreferredDeviceDispatcher dispatcher) {
- mDeviceInventory.unregisterStrategyPreferredDeviceDispatcher(dispatcher);
+ /*package*/ void unregisterStrategyPreferredDevicesDispatcher(
+ @NonNull IStrategyPreferredDevicesDispatcher dispatcher) {
+ mDeviceInventory.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
}
//---------------------------------------------------------------------
@@ -683,14 +684,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
sendLMsgNoDelay(MSG_L_SPEAKERPHONE_CLIENT_DIED, SENDMSG_QUEUE, obj);
}
- /*package*/ void postSaveSetPreferredDeviceForStrategy(int strategy,
- AudioDeviceAttributes device)
+ /*package*/ void postSaveSetPreferredDevicesForStrategy(int strategy,
+ List<AudioDeviceAttributes> devices)
{
- sendILMsgNoDelay(MSG_IL_SAVE_PREF_DEVICE_FOR_STRATEGY, SENDMSG_QUEUE, strategy, device);
+ sendILMsgNoDelay(MSG_IL_SAVE_PREF_DEVICES_FOR_STRATEGY, SENDMSG_QUEUE, strategy, devices);
}
- /*package*/ void postSaveRemovePreferredDeviceForStrategy(int strategy) {
- sendIMsgNoDelay(MSG_I_SAVE_REMOVE_PREF_DEVICE_FOR_STRATEGY, SENDMSG_QUEUE, strategy);
+ /*package*/ void postSaveRemovePreferredDevicesForStrategy(int strategy) {
+ sendIMsgNoDelay(MSG_I_SAVE_REMOVE_PREF_DEVICES_FOR_STRATEGY, SENDMSG_QUEUE, strategy);
}
//---------------------------------------------------------------------
@@ -1082,14 +1083,15 @@ import java.util.concurrent.atomic.AtomicBoolean;
info.mDevice, info.mState, info.mSupprNoisy, info.mMusicDevice);
}
} break;
- case MSG_IL_SAVE_PREF_DEVICE_FOR_STRATEGY: {
+ case MSG_IL_SAVE_PREF_DEVICES_FOR_STRATEGY: {
final int strategy = msg.arg1;
- final AudioDeviceAttributes device = (AudioDeviceAttributes) msg.obj;
- mDeviceInventory.onSaveSetPreferredDevice(strategy, device);
+ final List<AudioDeviceAttributes> devices =
+ (List<AudioDeviceAttributes>) msg.obj;
+ mDeviceInventory.onSaveSetPreferredDevices(strategy, devices);
} break;
- case MSG_I_SAVE_REMOVE_PREF_DEVICE_FOR_STRATEGY: {
+ case MSG_I_SAVE_REMOVE_PREF_DEVICES_FOR_STRATEGY: {
final int strategy = msg.arg1;
- mDeviceInventory.onSaveRemovePreferredDevice(strategy);
+ mDeviceInventory.onSaveRemovePreferredDevices(strategy);
} break;
case MSG_CHECK_MUTE_MUSIC:
checkMessagesMuteMusic(0);
@@ -1163,8 +1165,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
// a ScoClient died in BtHelper
private static final int MSG_L_SCOCLIENT_DIED = 32;
- private static final int MSG_IL_SAVE_PREF_DEVICE_FOR_STRATEGY = 33;
- private static final int MSG_I_SAVE_REMOVE_PREF_DEVICE_FOR_STRATEGY = 34;
+ private static final int MSG_IL_SAVE_PREF_DEVICES_FOR_STRATEGY = 33;
+ private static final int MSG_I_SAVE_REMOVE_PREF_DEVICES_FOR_STRATEGY = 34;
private static final int MSG_L_SPEAKERPHONE_CLIENT_DIED = 35;
private static final int MSG_CHECK_MUTE_MUSIC = 36;
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 02a846e3dc82..fbf07cc591ff 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -16,7 +16,6 @@
package com.android.server.audio;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.ActivityManager;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
@@ -32,7 +31,7 @@ import android.media.AudioPort;
import android.media.AudioRoutesInfo;
import android.media.AudioSystem;
import android.media.IAudioRoutesObserver;
-import android.media.IStrategyPreferredDeviceDispatcher;
+import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.MediaMetrics;
import android.os.Binder;
import android.os.RemoteCallbackList;
@@ -51,6 +50,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Set;
/**
@@ -137,7 +137,8 @@ public class AudioDeviceInventory {
private final ArrayMap<Integer, String> mApmConnectedDevices = new ArrayMap<>();
// List of preferred devices for strategies
- private final ArrayMap<Integer, AudioDeviceAttributes> mPreferredDevices = new ArrayMap<>();
+ private final ArrayMap<Integer, List<AudioDeviceAttributes>> mPreferredDevices =
+ new ArrayMap<>();
// the wrapper for AudioSystem static methods, allows us to spy AudioSystem
private final @NonNull AudioSystemAdapter mAudioSystem;
@@ -150,8 +151,8 @@ public class AudioDeviceInventory {
new RemoteCallbackList<IAudioRoutesObserver>();
// Monitoring of strategy-preferred device
- final RemoteCallbackList<IStrategyPreferredDeviceDispatcher> mPrefDevDispatchers =
- new RemoteCallbackList<IStrategyPreferredDeviceDispatcher>();
+ final RemoteCallbackList<IStrategyPreferredDevicesDispatcher> mPrefDevDispatchers =
+ new RemoteCallbackList<IStrategyPreferredDevicesDispatcher>();
/*package*/ AudioDeviceInventory(@NonNull AudioDeviceBroker broker) {
mDeviceBroker = broker;
@@ -265,8 +266,9 @@ public class AudioDeviceInventory {
}
}
synchronized (mPreferredDevices) {
- mPreferredDevices.forEach((strategy, device) -> {
- mAudioSystem.setPreferredDeviceForStrategy(strategy, device); });
+ mPreferredDevices.forEach((strategy, devices) -> {
+ mAudioSystem.setDevicesRoleForStrategy(
+ strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); });
}
}
@@ -600,49 +602,52 @@ public class AudioDeviceInventory {
mmi.record();
}
- /*package*/ void onSaveSetPreferredDevice(int strategy, @NonNull AudioDeviceAttributes device) {
- mPreferredDevices.put(strategy, device);
- dispatchPreferredDevice(strategy, device);
+ /*package*/ void onSaveSetPreferredDevices(int strategy,
+ @NonNull List<AudioDeviceAttributes> devices) {
+ mPreferredDevices.put(strategy, devices);
+ dispatchPreferredDevice(strategy, devices);
}
- /*package*/ void onSaveRemovePreferredDevice(int strategy) {
+ /*package*/ void onSaveRemovePreferredDevices(int strategy) {
mPreferredDevices.remove(strategy);
- dispatchPreferredDevice(strategy, null);
+ dispatchPreferredDevice(strategy, new ArrayList<AudioDeviceAttributes>());
}
//------------------------------------------------------------
//
- /*package*/ int setPreferredDeviceForStrategySync(int strategy,
- @NonNull AudioDeviceAttributes device) {
+ /*package*/ int setPreferredDevicesForStrategySync(int strategy,
+ @NonNull List<AudioDeviceAttributes> devices) {
final long identity = Binder.clearCallingIdentity();
- final int status = mAudioSystem.setPreferredDeviceForStrategy(strategy, device);
+ final int status = mAudioSystem.setDevicesRoleForStrategy(
+ strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
Binder.restoreCallingIdentity(identity);
if (status == AudioSystem.SUCCESS) {
- mDeviceBroker.postSaveSetPreferredDeviceForStrategy(strategy, device);
+ mDeviceBroker.postSaveSetPreferredDevicesForStrategy(strategy, devices);
}
return status;
}
- /*package*/ int removePreferredDeviceForStrategySync(int strategy) {
+ /*package*/ int removePreferredDevicesForStrategySync(int strategy) {
final long identity = Binder.clearCallingIdentity();
- final int status = mAudioSystem.removePreferredDeviceForStrategy(strategy);
+ final int status = mAudioSystem.removeDevicesRoleForStrategy(
+ strategy, AudioSystem.DEVICE_ROLE_PREFERRED);
Binder.restoreCallingIdentity(identity);
if (status == AudioSystem.SUCCESS) {
- mDeviceBroker.postSaveRemovePreferredDeviceForStrategy(strategy);
+ mDeviceBroker.postSaveRemovePreferredDevicesForStrategy(strategy);
}
return status;
}
- /*package*/ void registerStrategyPreferredDeviceDispatcher(
- @NonNull IStrategyPreferredDeviceDispatcher dispatcher) {
+ /*package*/ void registerStrategyPreferredDevicesDispatcher(
+ @NonNull IStrategyPreferredDevicesDispatcher dispatcher) {
mPrefDevDispatchers.register(dispatcher);
}
- /*package*/ void unregisterStrategyPreferredDeviceDispatcher(
- @NonNull IStrategyPreferredDeviceDispatcher dispatcher) {
+ /*package*/ void unregisterStrategyPreferredDevicesDispatcher(
+ @NonNull IStrategyPreferredDevicesDispatcher dispatcher) {
mPrefDevDispatchers.unregister(dispatcher);
}
@@ -1288,11 +1293,13 @@ public class AudioDeviceInventory {
}
}
- private void dispatchPreferredDevice(int strategy, @Nullable AudioDeviceAttributes device) {
+ private void dispatchPreferredDevice(int strategy,
+ @NonNull List<AudioDeviceAttributes> devices) {
final int nbDispatchers = mPrefDevDispatchers.beginBroadcast();
for (int i = 0; i < nbDispatchers; i++) {
try {
- mPrefDevDispatchers.getBroadcastItem(i).dispatchPrefDeviceChanged(strategy, device);
+ mPrefDevDispatchers.getBroadcastItem(i).dispatchPrefDevicesChanged(
+ strategy, devices);
} catch (RemoteException e) {
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 23b09294260c..bf7c68a845c5 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -83,7 +83,7 @@ import android.media.IAudioService;
import android.media.IPlaybackConfigDispatcher;
import android.media.IRecordingConfigDispatcher;
import android.media.IRingtonePlayer;
-import android.media.IStrategyPreferredDeviceDispatcher;
+import android.media.IStrategyPreferredDevicesDispatcher;
import android.media.IVolumeController;
import android.media.MediaExtractor;
import android.media.MediaFormat;
@@ -167,6 +167,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
/**
* The implementation of the audio service for volume, audio focus, device management...
@@ -1282,7 +1283,6 @@ public class AudioService extends IAudioService.Stub
}
if (isPlatformTelevision()) {
- checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI, caller);
synchronized (mHdmiClientLock) {
if (mHdmiManager != null && mHdmiPlaybackClient != null) {
updateHdmiCecSinkLocked(mHdmiCecSink | false);
@@ -1302,22 +1302,54 @@ public class AudioService extends IAudioService.Stub
}
}
- private void checkAddAllFixedVolumeDevices(int device, String caller) {
+ /**
+ * Update volume states for the given device.
+ *
+ * This will initialize the volume index if no volume index is available.
+ * If the device is the currently routed device, fixed/full volume policies will be applied.
+ *
+ * @param device a single audio device, ensure that this is not a devices bitmask
+ * @param caller caller of this method
+ */
+ private void updateVolumeStatesForAudioDevice(int device, String caller) {
final int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = 0; streamType < numStreamTypes; streamType++) {
- if (!mStreamStates[streamType].hasIndexForDevice(device)) {
- // set the default value, if device is affected by a full/fix/abs volume rule, it
- // will taken into account in checkFixedVolumeDevices()
- mStreamStates[streamType].setIndex(
- mStreamStates[mStreamVolumeAlias[streamType]]
- .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
- device, caller, true /*hasModifyAudioSettings*/);
- }
- mStreamStates[streamType].checkFixedVolumeDevices();
+ updateVolumeStates(device, streamType, caller);
+ }
+ }
- // Unmute streams if device is full volume
- if (mFullVolumeDevices.contains(device)) {
- mStreamStates[streamType].mute(false);
+ /**
+ * Update volume states for the given device and given stream.
+ *
+ * This will initialize the volume index if no volume index is available.
+ * If the device is the currently routed device, fixed/full volume policies will be applied.
+ *
+ * @param device a single audio device, ensure that this is not a devices bitmask
+ * @param streamType streamType to be updated
+ * @param caller caller of this method
+ */
+ private void updateVolumeStates(int device, int streamType, String caller) {
+ if (!mStreamStates[streamType].hasIndexForDevice(device)) {
+ // set the default value, if device is affected by a full/fix/abs volume rule, it
+ // will taken into account in checkFixedVolumeDevices()
+ mStreamStates[streamType].setIndex(
+ mStreamStates[mStreamVolumeAlias[streamType]]
+ .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
+ device, caller, true /*hasModifyAudioSettings*/);
+ }
+
+ // Check if device to be updated is routed for the given audio stream
+ List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt(
+ new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build());
+ for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) {
+ if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType(
+ device)) {
+ mStreamStates[streamType].checkFixedVolumeDevices();
+
+ // Unmute streams if required if device is full volume
+ if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) {
+ mStreamStates[streamType].mute(false);
+ }
}
}
}
@@ -1777,22 +1809,28 @@ public class AudioService extends IAudioService.Stub
///////////////////////////////////////////////////////////////////////////
// IPC methods
///////////////////////////////////////////////////////////////////////////
- /** @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceInfo) */
- public int setPreferredDeviceForStrategy(int strategy, AudioDeviceAttributes device) {
- if (device == null) {
+ /**
+ * @see AudioManager#setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
+ * @see AudioManager#setPreferredDevicesForStrategy(AudioProductStrategy,
+ * List<AudioDeviceAttributes>)
+ */
+ public int setPreferredDevicesForStrategy(int strategy, List<AudioDeviceAttributes> devices) {
+ if (devices == null) {
return AudioSystem.ERROR;
}
enforceModifyAudioRoutingPermission();
final String logString = String.format(
"setPreferredDeviceForStrategy u/pid:%d/%d strat:%d dev:%s",
- Binder.getCallingUid(), Binder.getCallingPid(), strategy, device.toString());
+ Binder.getCallingUid(), Binder.getCallingPid(), strategy,
+ devices.stream().map(e -> e.toString()).collect(Collectors.joining(",")));
sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
- if (device.getRole() == AudioDeviceAttributes.ROLE_INPUT) {
+ if (devices.stream().anyMatch(device ->
+ device.getRole() == AudioDeviceAttributes.ROLE_INPUT)) {
Log.e(TAG, "Unsupported input routing in " + logString);
return AudioSystem.ERROR;
}
- final int status = mDeviceBroker.setPreferredDeviceForStrategySync(strategy, device);
+ final int status = mDeviceBroker.setPreferredDevicesForStrategySync(strategy, devices);
if (status != AudioSystem.SUCCESS) {
Log.e(TAG, String.format("Error %d in %s)", status, logString));
}
@@ -1801,60 +1839,73 @@ public class AudioService extends IAudioService.Stub
}
/** @see AudioManager#removePreferredDeviceForStrategy(AudioProductStrategy) */
- public int removePreferredDeviceForStrategy(int strategy) {
+ public int removePreferredDevicesForStrategy(int strategy) {
enforceModifyAudioRoutingPermission();
final String logString =
String.format("removePreferredDeviceForStrategy strat:%d", strategy);
sDeviceLogger.log(new AudioEventLogger.StringEvent(logString).printLog(TAG));
- final int status = mDeviceBroker.removePreferredDeviceForStrategySync(strategy);
+ final int status = mDeviceBroker.removePreferredDevicesForStrategySync(strategy);
if (status != AudioSystem.SUCCESS) {
Log.e(TAG, String.format("Error %d in %s)", status, logString));
}
return status;
}
- /** @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy) */
- public AudioDeviceAttributes getPreferredDeviceForStrategy(int strategy) {
+ /**
+ * @see AudioManager#getPreferredDeviceForStrategy(AudioProductStrategy)
+ * @see AudioManager#getPreferredDevicesForStrategy(AudioProductStrategy)
+ */
+ public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(int strategy) {
enforceModifyAudioRoutingPermission();
- AudioDeviceAttributes[] devices = new AudioDeviceAttributes[1];
+ List<AudioDeviceAttributes> devices = new ArrayList<>();
final long identity = Binder.clearCallingIdentity();
- final int status = AudioSystem.getPreferredDeviceForStrategy(strategy, devices);
+ final int status = AudioSystem.getDevicesForRoleAndStrategy(
+ strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
Binder.restoreCallingIdentity(identity);
if (status != AudioSystem.SUCCESS) {
Log.e(TAG, String.format("Error %d in getPreferredDeviceForStrategy(%d)",
status, strategy));
- return null;
+ return new ArrayList<AudioDeviceAttributes>();
} else {
- return devices[0];
+ return devices;
}
}
- /** @see AudioManager#addOnPreferredDeviceForStrategyChangedListener(Executor, AudioManager.OnPreferredDeviceForStrategyChangedListener) */
- public void registerStrategyPreferredDeviceDispatcher(
- @Nullable IStrategyPreferredDeviceDispatcher dispatcher) {
+ /** @see AudioManager#addOnPreferredDevicesForStrategyChangedListener(
+ * Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener)
+ */
+ public void registerStrategyPreferredDevicesDispatcher(
+ @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
if (dispatcher == null) {
return;
}
enforceModifyAudioRoutingPermission();
- mDeviceBroker.registerStrategyPreferredDeviceDispatcher(dispatcher);
+ mDeviceBroker.registerStrategyPreferredDevicesDispatcher(dispatcher);
}
- /** @see AudioManager#removeOnPreferredDeviceForStrategyChangedListener(AudioManager.OnPreferredDeviceForStrategyChangedListener) */
- public void unregisterStrategyPreferredDeviceDispatcher(
- @Nullable IStrategyPreferredDeviceDispatcher dispatcher) {
+ /** @see AudioManager#removeOnPreferredDevicesForStrategyChangedListener(
+ * AudioManager.OnPreferredDevicesForStrategyChangedListener)
+ */
+ public void unregisterStrategyPreferredDevicesDispatcher(
+ @Nullable IStrategyPreferredDevicesDispatcher dispatcher) {
if (dispatcher == null) {
return;
}
enforceModifyAudioRoutingPermission();
- mDeviceBroker.unregisterStrategyPreferredDeviceDispatcher(dispatcher);
+ mDeviceBroker.unregisterStrategyPreferredDevicesDispatcher(dispatcher);
}
/** @see AudioManager#getDevicesForAttributes(AudioAttributes) */
public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
@NonNull AudioAttributes attributes) {
- Objects.requireNonNull(attributes);
enforceModifyAudioRoutingPermission();
+ return getDevicesForAttributesInt(attributes);
+ }
+
+ protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt(
+ @NonNull AudioAttributes attributes) {
+ Objects.requireNonNull(attributes);
return AudioSystem.getDevicesForAttributes(attributes);
}
@@ -4901,7 +4952,15 @@ public class AudioService extends IAudioService.Stub
synchronized (VolumeStreamState.class) {
for (int stream = 0; stream < mStreamStates.length; stream++) {
if (stream != skipStream) {
- mStreamStates[stream].observeDevicesForStream_syncVSS(false /*checkOthers*/);
+ int devices = mStreamStates[stream].observeDevicesForStream_syncVSS(
+ false /*checkOthers*/);
+
+ Set<Integer> devicesSet = AudioSystem.generateAudioDeviceTypesSet(devices);
+ for (Integer device : devicesSet) {
+ // Update volume states for devices routed for the stream
+ updateVolumeStates(device, stream,
+ "AudioService#observeDevicesForStreams");
+ }
}
}
}
@@ -4970,7 +5029,7 @@ public class AudioService extends IAudioService.Stub
+ Integer.toHexString(audioSystemDeviceOut) + " from:" + caller));
// make sure we have a volume entry for this device, and that volume is updated according
// to volume behavior
- checkAddAllFixedVolumeDevices(audioSystemDeviceOut, "setDeviceVolumeBehavior:" + caller);
+ updateVolumeStatesForAudioDevice(audioSystemDeviceOut, "setDeviceVolumeBehavior:" + caller);
}
/**
@@ -7192,10 +7251,9 @@ public class AudioService extends IAudioService.Stub
// HDMI output
removeAudioSystemDeviceOutFromFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI);
}
+ updateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI,
+ "HdmiPlaybackClient.DisplayStatusCallback");
}
-
- checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI,
- "HdmiPlaybackClient.DisplayStatusCallback");
}
private class MyHdmiControlStatusChangeListenerCallback
diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
index e60243fc481c..a0e1ca78a5e7 100644
--- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java
+++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
@@ -20,6 +20,8 @@ import android.annotation.NonNull;
import android.media.AudioDeviceAttributes;
import android.media.AudioSystem;
+import java.util.List;
+
/**
* Provides an adapter to access functionality of the android.media.AudioSystem class for device
* related functionality.
@@ -77,22 +79,25 @@ public class AudioSystemAdapter {
}
/**
- * Same as {@link AudioSystem#setPreferredDeviceForStrategy(int, AudioDeviceAttributes)}
+ * Same as {@link AudioSystem#setDevicesRoleForStrategy(int, int, List)}
* @param strategy
- * @param device
+ * @param role
+ * @param devices
* @return
*/
- public int setPreferredDeviceForStrategy(int strategy, @NonNull AudioDeviceAttributes device) {
- return AudioSystem.setPreferredDeviceForStrategy(strategy, device);
+ public int setDevicesRoleForStrategy(int strategy, int role,
+ @NonNull List<AudioDeviceAttributes> devices) {
+ return AudioSystem.setDevicesRoleForStrategy(strategy, role, devices);
}
/**
- * Same as {@link AudioSystem#removePreferredDeviceForStrategy(int)}
+ * Same as {@link AudioSystem#removeDevicesRoleForStrategy(int, int)}
* @param strategy
+ * @param role
* @return
*/
- public int removePreferredDeviceForStrategy(int strategy) {
- return AudioSystem.removePreferredDeviceForStrategy(strategy);
+ public int removeDevicesRoleForStrategy(int strategy, int role) {
+ return AudioSystem.removeDevicesRoleForStrategy(strategy, role);
}
/**
diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
index ab48fdb0fd6e..e87c8fe092fe 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
@@ -98,7 +98,7 @@ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements I
}
if (finish) {
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
@@ -114,7 +114,7 @@ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements I
}
@Override
- public void cancelWithoutStarting(@NonNull FinishCallback finishCallback) {
+ public void cancelWithoutStarting(@NonNull Callback callback) {
final int errorCode = BiometricConstants.BIOMETRIC_ERROR_CANCELED;
try {
if (getListener() != null) {
@@ -123,7 +123,7 @@ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements I
} catch (RemoteException e) {
Slog.w(TAG, "Failed to invoke sendError", e);
}
- finishCallback.onClientFinished(this, true /* success */);
+ callback.onClientFinished(this, true /* success */);
}
/**
@@ -155,7 +155,7 @@ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements I
}
} catch (RemoteException e) {
Slog.w(TAG, "Failed to invoke sendAcquired", e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index cb2321f524f6..47c839cb329a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -191,7 +191,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
}
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify listener, finishing", e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
@@ -211,8 +211,8 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
* Start authentication
*/
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
final @LockoutTracker.LockoutMode int lockoutMode =
mLockoutTracker.getLockoutModeForUser(getTargetUserId());
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index 4f37dccea42e..fffc07320f84 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -85,7 +85,7 @@ public class BiometricScheduler {
static final int STATE_WAITING_FOR_COOKIE = 4;
/**
- * The {@link ClientMonitor.FinishCallback} has been invoked and the client is finished.
+ * The {@link ClientMonitor.Callback} has been invoked and the client is finished.
*/
static final int STATE_FINISHED = 5;
@@ -99,13 +99,13 @@ public class BiometricScheduler {
@interface OperationState {}
@NonNull final ClientMonitor<?> clientMonitor;
- @Nullable final ClientMonitor.FinishCallback clientFinishCallback;
+ @Nullable final ClientMonitor.Callback mClientCallback;
@OperationState int state;
Operation(@NonNull ClientMonitor<?> clientMonitor,
- @Nullable ClientMonitor.FinishCallback finishCallback) {
+ @Nullable ClientMonitor.Callback callback) {
this.clientMonitor = clientMonitor;
- this.clientFinishCallback = finishCallback;
+ this.mClientCallback = callback;
state = STATE_WAITING_IN_QUEUE;
}
@@ -133,7 +133,7 @@ public class BiometricScheduler {
public void run() {
if (operation.state != Operation.STATE_FINISHED) {
Slog.e(tag, "[Watchdog Triggered]: " + operation);
- operation.clientMonitor.mFinishCallback
+ operation.clientMonitor.mCallback
.onClientFinished(operation.clientMonitor, false /* success */);
}
}
@@ -175,15 +175,15 @@ public class BiometricScheduler {
@Nullable private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
@NonNull private final IBiometricService mBiometricService;
@NonNull private final Handler mHandler = new Handler(Looper.getMainLooper());
- @NonNull private final InternalFinishCallback mInternalFinishCallback;
+ @NonNull protected final InternalCallback mInternalCallback;
@NonNull private final Queue<Operation> mPendingOperations;
@Nullable private Operation mCurrentOperation;
@NonNull private final ArrayDeque<CrashState> mCrashStates;
- // Internal finish callback, notified when an operation is complete. Notifies the requester
+ // Internal callback, notified when an operation is complete. Notifies the requester
// that the operation is complete, before performing internal scheduler work (such as
// starting the next client).
- private class InternalFinishCallback implements ClientMonitor.FinishCallback {
+ public class InternalCallback implements ClientMonitor.Callback {
@Override
public void onClientFinished(ClientMonitor<?> clientMonitor, boolean success) {
mHandler.post(() -> {
@@ -203,8 +203,8 @@ public class BiometricScheduler {
Slog.d(getTag(), "[Finishing] " + clientMonitor + ", success: " + success);
mCurrentOperation.state = Operation.STATE_FINISHED;
- if (mCurrentOperation.clientFinishCallback != null) {
- mCurrentOperation.clientFinishCallback.onClientFinished(clientMonitor, success);
+ if (mCurrentOperation.mClientCallback != null) {
+ mCurrentOperation.mClientCallback.onClientFinished(clientMonitor, success);
}
if (mGestureAvailabilityDispatcher != null) {
@@ -227,7 +227,7 @@ public class BiometricScheduler {
public BiometricScheduler(@NonNull String tag,
@Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
mBiometricTag = tag;
- mInternalFinishCallback = new InternalFinishCallback();
+ mInternalCallback = new InternalCallback();
mGestureAvailabilityDispatcher = gestureAvailabilityDispatcher;
mPendingOperations = new ArrayDeque<>();
mBiometricService = IBiometricService.Stub.asInterface(
@@ -262,7 +262,7 @@ public class BiometricScheduler {
}
final Interruptable interruptable = (Interruptable) currentClient;
- interruptable.cancelWithoutStarting(mInternalFinishCallback);
+ interruptable.cancelWithoutStarting(mInternalCallback);
// Now we wait for the client to send its FinishCallback, which kicks off the next
// operation.
return;
@@ -280,7 +280,10 @@ public class BiometricScheduler {
final boolean shouldStartNow = currentClient.getCookie() == 0;
if (shouldStartNow) {
Slog.d(getTag(), "[Starting] " + mCurrentOperation);
- currentClient.start(mInternalFinishCallback);
+ if (mCurrentOperation.mClientCallback != null) {
+ mCurrentOperation.mClientCallback.onClientStarted(currentClient);
+ }
+ currentClient.start(mInternalCallback);
mCurrentOperation.state = Operation.STATE_STARTED;
} else {
try {
@@ -323,8 +326,11 @@ public class BiometricScheduler {
}
Slog.d(getTag(), "[Starting] Prepared client: " + mCurrentOperation);
+ if (mCurrentOperation.mClientCallback != null) {
+ mCurrentOperation.mClientCallback.onClientStarted(mCurrentOperation.clientMonitor);
+ }
mCurrentOperation.state = Operation.STATE_STARTED;
- mCurrentOperation.clientMonitor.start(mInternalFinishCallback);
+ mCurrentOperation.clientMonitor.start(mInternalCallback);
}
/**
@@ -340,11 +346,11 @@ public class BiometricScheduler {
* Adds a {@link ClientMonitor} to the pending queue
*
* @param clientMonitor operation to be scheduled
- * @param clientFinishCallback optional callback, invoked when the client is finished, but
+ * @param clientCallback optional callback, invoked when the client is finished, but
* before it has been removed from the queue.
*/
public void scheduleClientMonitor(@NonNull ClientMonitor<?> clientMonitor,
- @Nullable ClientMonitor.FinishCallback clientFinishCallback) {
+ @Nullable ClientMonitor.Callback clientCallback) {
// Mark any interruptable pending clients as canceling. Once they reach the head of the
// queue, the scheduler will send ERROR_CANCELED and skip the operation.
for (Operation operation : mPendingOperations) {
@@ -356,7 +362,7 @@ public class BiometricScheduler {
}
}
- mPendingOperations.add(new Operation(clientMonitor, clientFinishCallback));
+ mPendingOperations.add(new Operation(clientMonitor, clientCallback));
Slog.d(getTag(), "[Added] " + clientMonitor
+ ", new queue size: " + mPendingOperations.size());
diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java
index 8b27781940ac..81867b02aed9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java
@@ -42,7 +42,15 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde
/**
* Interface that ClientMonitor holders should use to receive callbacks.
*/
- public interface FinishCallback {
+ public interface Callback {
+ /**
+ * Invoked when the ClientMonitor operation has been started (e.g. reached the head of
+ * the queue and becomes the current operation).
+ *
+ * @param clientMonitor Reference of the ClientMonitor that is starting.
+ */
+ default void onClientStarted(@NonNull ClientMonitor<?> clientMonitor) {}
+
/**
* Invoked when the ClientMonitor operation is complete. This abstracts away asynchronous
* (i.e. Authenticate, Enroll, Enumerate, Remove) and synchronous (i.e. generateChallenge,
@@ -52,7 +60,7 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde
* @param clientMonitor Reference of the ClientMonitor that finished.
* @param success True if the operation completed successfully.
*/
- void onClientFinished(ClientMonitor<?> clientMonitor, boolean success);
+ default void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) {}
}
/**
@@ -79,7 +87,7 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde
private final int mCookie;
boolean mAlreadyDone;
- @NonNull protected FinishCallback mFinishCallback;
+ @NonNull protected Callback mCallback;
/**
* @param context system_server context
@@ -125,17 +133,17 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde
/**
* Invoked if the scheduler is unable to start the ClientMonitor (for example the HAL is null).
* If such a problem is detected, the scheduler will not invoke
- * {@link #start(FinishCallback)}.
+ * {@link #start(Callback)}.
*/
public abstract void unableToStart();
/**
* Starts the ClientMonitor's lifecycle. Invokes {@link #startHalOperation()} when internal book
* keeping is complete.
- * @param finishCallback invoked when the operation is complete (succeeds, fails, etc)
+ * @param callback invoked when the operation is complete (succeeds, fails, etc)
*/
- public void start(@NonNull FinishCallback finishCallback) {
- mFinishCallback = finishCallback;
+ public void start(@NonNull Callback callback) {
+ mCallback = callback;
}
/**
diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java
index 3cef6667b644..2c60d096bd13 100644
--- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java
+++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java
@@ -142,10 +142,21 @@ public final class ClientMonitorCallbackConverter {
}
}
- public void onFeatureGet(boolean success, int feature, boolean value)
- throws RemoteException {
+ public void onFeatureGet(boolean success, int feature, boolean value) throws RemoteException {
if (mFaceServiceReceiver != null) {
mFaceServiceReceiver.onFeatureGet(success, feature, value);
}
}
+
+ public void onChallengeInterrupted(int sensorId) throws RemoteException {
+ if (mFaceServiceReceiver != null) {
+ mFaceServiceReceiver.onChallengeInterrupted(sensorId);
+ }
+ }
+
+ public void onChallengeInterruptFinished(int sensorId) throws RemoteException {
+ if (mFaceServiceReceiver != null) {
+ mFaceServiceReceiver.onChallengeInterruptFinished(sensorId);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java
index add5829c1342..8bf9680d60cd 100644
--- a/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java
@@ -77,18 +77,18 @@ public abstract class EnrollClient<T> extends AcquisitionClient<T> {
mBiometricUtils.addBiometricForUser(getContext(), getTargetUserId(), identifier);
logOnEnrolled(getTargetUserId(), System.currentTimeMillis() - mEnrollmentStartTimeMs,
true /* enrollSuccessful */);
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
}
notifyUserActivity();
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
if (hasReachedEnrollmentLimit()) {
Slog.e(TAG, "Reached enrollment limit");
- finishCallback.onClientFinished(this, false /* success */);
+ callback.onClientFinished(this, false /* success */);
return;
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java
index dad5cad1ed8d..2c5b8027f309 100644
--- a/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java
@@ -47,16 +47,16 @@ public abstract class GenerateChallengeClient<T> extends ClientMonitor<T> {
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
startHalOperation();
try {
getListener().onChallengeGenerated(mChallenge);
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
index 6d7b0fd3d5f1..5c08bce9b44f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
@@ -62,29 +62,35 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide
private final List<S> mEnrolledList;
private ClientMonitor<T> mCurrentTask;
- private final FinishCallback mEnumerateFinishCallback = (clientMonitor, success) -> {
- final List<BiometricAuthenticator.Identifier> unknownHALTemplates =
- ((InternalEnumerateClient<T>) mCurrentTask).getUnknownHALTemplates();
-
- if (!unknownHALTemplates.isEmpty()) {
- Slog.w(TAG, "Adding " + unknownHALTemplates.size() + " templates for deletion");
- }
- for (BiometricAuthenticator.Identifier unknownHALTemplate : unknownHALTemplates) {
- mUnknownHALTemplates.add(new UserTemplate(unknownHALTemplate,
- mCurrentTask.getTargetUserId()));
- }
-
- if (mUnknownHALTemplates.isEmpty()) {
- // No unknown HAL templates. Unknown framework templates are already cleaned up in
- // InternalEnumerateClient. Finish this client.
- mFinishCallback.onClientFinished(this, success);
- } else {
- startCleanupUnknownHalTemplates();
+ private final Callback mEnumerateCallback = new Callback() {
+ @Override
+ public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) {
+ final List<BiometricAuthenticator.Identifier> unknownHALTemplates =
+ ((InternalEnumerateClient<T>) mCurrentTask).getUnknownHALTemplates();
+
+ if (!unknownHALTemplates.isEmpty()) {
+ Slog.w(TAG, "Adding " + unknownHALTemplates.size() + " templates for deletion");
+ }
+ for (BiometricAuthenticator.Identifier unknownHALTemplate : unknownHALTemplates) {
+ mUnknownHALTemplates.add(new UserTemplate(unknownHALTemplate,
+ mCurrentTask.getTargetUserId()));
+ }
+
+ if (mUnknownHALTemplates.isEmpty()) {
+ // No unknown HAL templates. Unknown framework templates are already cleaned up in
+ // InternalEnumerateClient. Finish this client.
+ mCallback.onClientFinished(InternalCleanupClient.this, success);
+ } else {
+ startCleanupUnknownHalTemplates();
+ }
}
};
- private final FinishCallback mRemoveFinishCallback = (clientMonitor, success) -> {
- mFinishCallback.onClientFinished(this, success);
+ private final Callback mRemoveCallback = new Callback() {
+ @Override
+ public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) {
+ mCallback.onClientFinished(InternalCleanupClient.this, success);
+ }
};
protected abstract InternalEnumerateClient<T> getEnumerateClient(Context context,
@@ -116,7 +122,7 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
mStatsModality,
BiometricsProtoEnums.ISSUE_UNKNOWN_TEMPLATE_ENROLLED_HAL);
- mCurrentTask.start(mRemoveFinishCallback);
+ mCurrentTask.start(mRemoveCallback);
}
@Override
@@ -125,13 +131,13 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
// Start enumeration. Removal will start if necessary, when enumeration is completed.
mCurrentTask = getEnumerateClient(getContext(), mLazyDaemon, getToken(), getTargetUserId(),
getOwnerString(), mEnrolledList, mBiometricUtils, getSensorId());
- mCurrentTask.start(mEnumerateFinishCallback);
+ mCurrentTask.start(mEnumerateCallback);
}
@Override
@@ -147,7 +153,7 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide
+ mCurrentTask.getClass().getSimpleName());
return;
}
- ((RemovalClient) mCurrentTask).onRemoved(identifier, remaining);
+ ((RemovalClient<T>) mCurrentTask).onRemoved(identifier, remaining);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/InternalEnumerateClient.java b/services/core/java/com/android/server/biometrics/sensors/InternalEnumerateClient.java
index 3f73cd56e6c3..e07f71298d13 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InternalEnumerateClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InternalEnumerateClient.java
@@ -62,7 +62,7 @@ public abstract class InternalEnumerateClient<T> extends ClientMonitor<T>
handleEnumeratedTemplate(identifier);
if (remaining == 0) {
doTemplateCleanup();
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
}
}
@@ -72,8 +72,8 @@ public abstract class InternalEnumerateClient<T> extends ClientMonitor<T>
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
// The biometric template ids will be removed when we get confirmation from the HAL
startHalOperation();
diff --git a/services/core/java/com/android/server/biometrics/sensors/Interruptable.java b/services/core/java/com/android/server/biometrics/sensors/Interruptable.java
index 35d917747574..28e0117afd36 100644
--- a/services/core/java/com/android/server/biometrics/sensors/Interruptable.java
+++ b/services/core/java/com/android/server/biometrics/sensors/Interruptable.java
@@ -37,10 +37,10 @@ public interface Interruptable {
/**
* Notifies the client that it needs to finish before
- * {@link ClientMonitor#start(ClientMonitor.FinishCallback)} was invoked. This usually happens
+ * {@link ClientMonitor#start(ClientMonitor.Callback)} was invoked. This usually happens
* if the client is still waiting in the pending queue and got notified that a subsequent
* operation is preempting it.
- * @param finishCallback invoked when the operation is completed.
+ * @param callback invoked when the operation is completed.
*/
- void cancelWithoutStarting(@NonNull ClientMonitor.FinishCallback finishCallback);
+ void cancelWithoutStarting(@NonNull ClientMonitor.Callback callback);
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
index 1c49bcdbadf4..1348f797a2dc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
@@ -55,8 +55,8 @@ public abstract class RemovalClient<T> extends ClientMonitor<T> implements Remov
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
// The biometric template ids will be removed when we get confirmation from the HAL
startHalOperation();
@@ -85,7 +85,7 @@ public abstract class RemovalClient<T> extends ClientMonitor<T> implements Remov
// cleanup).
mAuthenticatorIds.put(getTargetUserId(), 0L);
}
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/RevokeChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/RevokeChallengeClient.java
index b78ee49826f2..5deb8fa26639 100644
--- a/services/core/java/com/android/server/biometrics/sensors/RevokeChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/RevokeChallengeClient.java
@@ -36,10 +36,10 @@ public abstract class RevokeChallengeClient<T> extends ClientMonitor<T> {
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
startHalOperation();
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
index 6c57208c1e84..a4956cb56527 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
@@ -98,6 +98,11 @@ class Face10 implements IHwBinder.DeathRecipient {
@Nullable private IBiometricsFace mDaemon;
private int mCurrentUserId = UserHandle.USER_NULL;
+ // If a challenge is generated, keep track of its owner. Since IBiometricsFace@1.0 only
+ // supports a single in-flight challenge, we must notify the interrupted owner that its
+ // challenge is no longer valid. The interrupted owner will be notified when the interrupter
+ // has finished.
+ @Nullable private FaceGenerateChallengeClient mCurrentChallengeOwner;
private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() {
@Override
@@ -394,9 +399,12 @@ class Face10 implements IHwBinder.DeathRecipient {
final FaceUpdateActiveUserClient client = new FaceUpdateActiveUserClient(mContext,
mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorId, mCurrentUserId,
hasEnrolled, mAuthenticatorIds);
- mScheduler.scheduleClientMonitor(client, (clientMonitor, success) -> {
- if (success) {
- mCurrentUserId = targetUserId;
+ mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
+ @Override
+ public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) {
+ if (success) {
+ mCurrentUserId = targetUserId;
+ }
}
});
}
@@ -459,18 +467,68 @@ class Face10 implements IHwBinder.DeathRecipient {
void scheduleGenerateChallenge(@NonNull IBinder token, @NonNull IFaceServiceReceiver receiver,
@NonNull String opPackageName) {
mHandler.post(() -> {
+ if (mCurrentChallengeOwner != null) {
+ Slog.w(TAG, "Current challenge owner: " + mCurrentChallengeOwner
+ + ", interrupted by: " + opPackageName);
+ try {
+ mCurrentChallengeOwner.getListener().onChallengeInterrupted(mSensorId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to notify challenge interrupted", e);
+ }
+ }
+
final FaceGenerateChallengeClient client = new FaceGenerateChallengeClient(mContext,
mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), opPackageName,
- mSensorId);
- mScheduler.scheduleClientMonitor(client);
+ mSensorId, mCurrentChallengeOwner);
+ mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
+ @Override
+ public void onClientStarted(@NonNull ClientMonitor<?> clientMonitor) {
+ if (client != clientMonitor) {
+ Slog.e(TAG, "scheduleGenerateChallenge, mismatched client."
+ + " Expecting: " + client + ", received: " + clientMonitor);
+ return;
+ }
+ Slog.d(TAG, "Current challenge owner: " + client);
+ mCurrentChallengeOwner = client;
+ }
+ });
});
}
void scheduleRevokeChallenge(@NonNull IBinder token, @NonNull String owner) {
mHandler.post(() -> {
+ if (!mCurrentChallengeOwner.getOwnerString().contentEquals(owner)) {
+ Slog.e(TAG, "Package: " + owner + " attempting to revoke challenge owned by: "
+ + mCurrentChallengeOwner.getOwnerString());
+ return;
+ }
+
final FaceRevokeChallengeClient client = new FaceRevokeChallengeClient(mContext,
mLazyDaemon, token, owner, mSensorId);
- mScheduler.scheduleClientMonitor(client);
+ mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
+ @Override
+ public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor,
+ boolean success) {
+ if (client != clientMonitor) {
+ Slog.e(TAG, "scheduleRevokeChallenge, mismatched client."
+ + "Expecting: " + client + ", received: " + clientMonitor);
+ return;
+ }
+
+ final FaceGenerateChallengeClient previousChallengeOwner =
+ mCurrentChallengeOwner.getInterruptedClient();
+ mCurrentChallengeOwner = null;
+ Slog.d(TAG, "Previous challenge owner: " + previousChallengeOwner);
+ if (previousChallengeOwner != null) {
+ try {
+ previousChallengeOwner.getListener()
+ .onChallengeInterruptFinished(mSensorId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to notify interrupt finished", e);
+ }
+ }
+ }
+ });
});
}
@@ -488,12 +546,16 @@ class Face10 implements IHwBinder.DeathRecipient {
opPackageName, FaceUtils.getInstance(), disabledFeatures, ENROLL_TIMEOUT_SEC,
surfaceHandle, mSensorId);
- mScheduler.scheduleClientMonitor(client, ((clientMonitor, success) -> {
- if (success) {
- // Update authenticatorIds
- scheduleUpdateActiveUserWithoutHandler(client.getTargetUserId());
+ mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
+ @Override
+ public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor,
+ boolean success) {
+ if (success) {
+ // Update authenticatorIds
+ scheduleUpdateActiveUserWithoutHandler(client.getTargetUserId());
+ }
}
- }));
+ });
});
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java
index 21bda74bc6b9..892d6a48488d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java
@@ -92,7 +92,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting auth", e);
onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
@@ -103,7 +103,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting cancel", e);
onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
@@ -131,7 +131,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
// 1) Authenticated == true
// 2) Error occurred
// 3) Authenticated == false
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java
index 52a822675c2f..3e843cae96fd 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java
@@ -116,12 +116,12 @@ public class FaceEnrollClient extends EnrollClient<IBiometricsFace> {
}
if (status != Status.OK) {
onError(BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS, 0 /* vendorCode */);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting enroll", e);
onError(BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS, 0 /* vendorCode */);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
@@ -132,7 +132,7 @@ public class FaceEnrollClient extends EnrollClient<IBiometricsFace> {
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting cancel", e);
onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java
index 67f2712d0b9d..ba401f255e43 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceGenerateChallengeClient.java
@@ -17,12 +17,14 @@
package com.android.server.biometrics.sensors.face;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.sensors.ClientMonitor;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.GenerateChallengeClient;
@@ -36,10 +38,22 @@ public class FaceGenerateChallengeClient extends GenerateChallengeClient<IBiomet
private static final String TAG = "FaceGenerateChallengeClient";
private static final int CHALLENGE_TIMEOUT_SEC = 600; // 10 minutes
+ // If `this` FaceGenerateChallengeClient was invoked while an existing in-flight challenge
+ // was not revoked yet, store a reference to the interrupted client here. Notify the interrupted
+ // client when `this` challenge is revoked.
+ @Nullable private final FaceGenerateChallengeClient mInterruptedClient;
+
FaceGenerateChallengeClient(@NonNull Context context,
@NonNull LazyDaemon<IBiometricsFace> lazyDaemon, @NonNull IBinder token,
- @NonNull ClientMonitorCallbackConverter listener, @NonNull String owner, int sensorId) {
+ @NonNull ClientMonitorCallbackConverter listener, @NonNull String owner, int sensorId,
+ @Nullable FaceGenerateChallengeClient interruptedClient) {
super(context, lazyDaemon, token, listener, owner, sensorId);
+ mInterruptedClient = interruptedClient;
+ }
+
+ @Nullable
+ public FaceGenerateChallengeClient getInterruptedClient() {
+ return mInterruptedClient;
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java
index ce57cb7686ed..8c7b99d6eb52 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java
@@ -61,8 +61,8 @@ public class FaceGetFeatureClient extends ClientMonitor<IBiometricsFace> {
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
startHalOperation();
}
@@ -71,10 +71,10 @@ public class FaceGetFeatureClient extends ClientMonitor<IBiometricsFace> {
try {
final OptionalBool result = getFreshDaemon().getFeature(mFeature, mFaceId);
getListener().onFeatureGet(result.status == Status.OK, mFeature, result.value);
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to getFeature", e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceInternalEnumerateClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceInternalEnumerateClient.java
index f25242ee9b85..32d48321428a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceInternalEnumerateClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceInternalEnumerateClient.java
@@ -52,7 +52,7 @@ class FaceInternalEnumerateClient extends InternalEnumerateClient<IBiometricsFac
getFreshDaemon().enumerate();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting enumerate", e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceRemovalClient.java
index 00d5f500b241..dde5ababd6c0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceRemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceRemovalClient.java
@@ -51,7 +51,7 @@ class FaceRemovalClient extends RemovalClient<IBiometricsFace> {
getFreshDaemon().remove(mBiometricId);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting remove", e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java
index 69070da0491e..f4324bedb4c6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java
@@ -56,8 +56,8 @@ public class FaceResetLockoutClient extends ClientMonitor<IBiometricsFace> {
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
startHalOperation();
}
@@ -65,10 +65,10 @@ public class FaceResetLockoutClient extends ClientMonitor<IBiometricsFace> {
protected void startHalOperation() {
try {
getFreshDaemon().resetLockout(mHardwareAuthToken);
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to reset lockout", e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java
index e7d041a11ccb..94abb7f378df 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java
@@ -70,8 +70,8 @@ public class FaceSetFeatureClient extends ClientMonitor<IBiometricsFace> {
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
startHalOperation();
}
@@ -82,10 +82,10 @@ public class FaceSetFeatureClient extends ClientMonitor<IBiometricsFace> {
final int result = getFreshDaemon()
.setFeature(mFeature, mEnabled, mHardwareAuthToken, mFaceId);
getListener().onFeatureSet(result == Status.OK, mFeature);
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to set feature: " + mFeature + " to enabled: " + mEnabled, e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java
index bcf304e47816..05b176d28e28 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java
@@ -50,8 +50,8 @@ public class FaceUpdateActiveUserClient extends ClientMonitor<IBiometricsFace> {
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
if (mCurrentUserId == getTargetUserId()) {
Slog.d(TAG, "Already user: " + mCurrentUserId + ", refreshing authenticatorId");
@@ -61,7 +61,7 @@ public class FaceUpdateActiveUserClient extends ClientMonitor<IBiometricsFace> {
} catch (RemoteException e) {
Slog.e(TAG, "Unable to refresh authenticatorId", e);
}
- finishCallback.onClientFinished(this, true /* success */);
+ callback.onClientFinished(this, true /* success */);
return;
}
@@ -79,16 +79,16 @@ public class FaceUpdateActiveUserClient extends ClientMonitor<IBiometricsFace> {
FACE_DATA_DIR);
if (!storePath.exists()) {
Slog.e(TAG, "vold has not created the directory?");
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
return;
}
try {
getFreshDaemon().setActiveUser(getTargetUserId(), storePath.getAbsolutePath());
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to setActiveUser: " + e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java
index dad038626762..20a180712b5b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java
@@ -409,9 +409,12 @@ class Fingerprint21 implements IHwBinder.DeathRecipient {
new FingerprintUpdateActiveUserClient(mContext, mLazyDaemon, targetUserId,
mContext.getOpPackageName(), mSensorProperties.sensorId, mCurrentUserId,
hasEnrolled, mAuthenticatorIds);
- mScheduler.scheduleClientMonitor(client, (clientMonitor, success) -> {
- if (success) {
- mCurrentUserId = targetUserId;
+ mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
+ @Override
+ public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) {
+ if (success) {
+ mCurrentUserId = targetUserId;
+ }
}
});
}
@@ -453,12 +456,16 @@ class Fingerprint21 implements IHwBinder.DeathRecipient {
mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
hardwareAuthToken, opPackageName, FingerprintUtils.getInstance(),
ENROLL_TIMEOUT_SEC, mSensorProperties.sensorId, mUdfpsOverlayController);
- mScheduler.scheduleClientMonitor(client, ((clientMonitor, success) -> {
- if (success) {
- // Update authenticatorIds
- scheduleUpdateActiveUserWithoutHandler(clientMonitor.getTargetUserId());
+ mScheduler.scheduleClientMonitor(client, new ClientMonitor.Callback() {
+ @Override
+ public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor,
+ boolean success) {
+ if (success) {
+ // Update authenticatorIds
+ scheduleUpdateActiveUserWithoutHandler(clientMonitor.getTargetUserId());
+ }
}
- }));
+ });
});
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticationClient.java
index 1564056cfdbd..751df8ef9925 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticationClient.java
@@ -79,7 +79,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
if (authenticated) {
resetFailedAttempts(getTargetUserId());
UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController);
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
} else {
final @LockoutTracker.LockoutMode int lockoutMode =
mLockoutFrameworkImpl.getLockoutModeForUser(getTargetUserId());
@@ -119,7 +119,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
@@ -132,7 +132,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
Slog.e(TAG, "Remote exception when requesting cancel", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintDetectClient.java
index 8b295f8f4931..8652ee403089 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintDetectClient.java
@@ -68,13 +68,13 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
Slog.e(TAG, "Remote exception when requesting cancel", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
startHalOperation();
}
@@ -88,7 +88,7 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintEnrollClient.java
index 32f8b8fe8b26..d5db6e411b95 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintEnrollClient.java
@@ -79,7 +79,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
UdfpsHelper.hideUdfpsOverlay(mUdfpsOverlayController);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
@@ -92,7 +92,7 @@ public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint
Slog.e(TAG, "Remote exception when requesting cancel", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintInternalEnumerateClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintInternalEnumerateClient.java
index 240c3c56f75e..834bf42eba3f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintInternalEnumerateClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintInternalEnumerateClient.java
@@ -52,7 +52,7 @@ class FingerprintInternalEnumerateClient extends InternalEnumerateClient<IBiomet
getFreshDaemon().enumerate();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting enumerate", e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintRemovalClient.java
index a9336ef6a6c2..9f5456300884 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintRemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintRemovalClient.java
@@ -54,7 +54,7 @@ class FingerprintRemovalClient extends RemovalClient<IBiometricsFingerprint> {
getFreshDaemon().remove(getTargetUserId(), mBiometricId);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting remove", e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUpdateActiveUserClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUpdateActiveUserClient.java
index e1082ae51575..c1c3593db564 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUpdateActiveUserClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUpdateActiveUserClient.java
@@ -22,7 +22,6 @@ import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
import android.os.Build;
import android.os.Environment;
-import android.os.IBinder;
import android.os.RemoteException;
import android.os.SELinux;
import android.util.Slog;
@@ -58,8 +57,8 @@ public class FingerprintUpdateActiveUserClient extends ClientMonitor<IBiometrics
}
@Override
- public void start(@NonNull FinishCallback finishCallback) {
- super.start(finishCallback);
+ public void start(@NonNull Callback callback) {
+ super.start(callback);
if (mCurrentUserId == getTargetUserId()) {
Slog.d(TAG, "Already user: " + mCurrentUserId + ", refreshing authenticatorId");
@@ -69,7 +68,7 @@ public class FingerprintUpdateActiveUserClient extends ClientMonitor<IBiometrics
} catch (RemoteException e) {
Slog.e(TAG, "Unable to refresh authenticatorId", e);
}
- finishCallback.onClientFinished(this, true /* success */);
+ callback.onClientFinished(this, true /* success */);
return;
}
@@ -89,7 +88,7 @@ public class FingerprintUpdateActiveUserClient extends ClientMonitor<IBiometrics
if (!mDirectory.exists()) {
if (!mDirectory.mkdir()) {
Slog.e(TAG, "Cannot make directory: " + mDirectory.getAbsolutePath());
- finishCallback.onClientFinished(this, false /* success */);
+ callback.onClientFinished(this, false /* success */);
return;
}
// Calling mkdir() from this process will create a directory with our
@@ -97,7 +96,7 @@ public class FingerprintUpdateActiveUserClient extends ClientMonitor<IBiometrics
// the label.
if (!SELinux.restorecon(mDirectory)) {
Slog.e(TAG, "Restorecons failed. Directory will have wrong label.");
- finishCallback.onClientFinished(this, false /* success */);
+ callback.onClientFinished(this, false /* success */);
return;
}
}
@@ -116,10 +115,10 @@ public class FingerprintUpdateActiveUserClient extends ClientMonitor<IBiometrics
getFreshDaemon().setActiveGroup(getTargetUserId(), mDirectory.getAbsolutePath());
mAuthenticatorIds.put(getTargetUserId(), mHasEnrolledBiometrics
? getFreshDaemon().getAuthenticatorId() : 0L);
- mFinishCallback.onClientFinished(this, true /* success */);
+ mCallback.onClientFinished(this, true /* success */);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to setActiveGroup: " + e);
- mFinishCallback.onClientFinished(this, false /* success */);
+ mCallback.onClientFinished(this, false /* success */);
}
}
}
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 7202f0f401f9..7f9b3c9fcff7 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -56,7 +56,6 @@ import android.system.OsConstants;
import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
-import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -130,7 +129,42 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
}
}
- public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd) {
+ /**
+ * A data class to store each uid Netd permission information. Netd permissions includes
+ * PERMISSION_NETWORK, PERMISSION_SYSTEM, PERMISSION_INTERNET, PERMISSION_UPDATE_DEVICE_STATS
+ * and OR'd with the others. Default permission is PERMISSION_NONE and PERMISSION_UNINSTALLED
+ * will be set if all packages are removed from the uid.
+ */
+ public static class UidNetdPermissionInfo {
+ private final int mNetdPermissions;
+
+ UidNetdPermissionInfo() {
+ this(PERMISSION_NONE);
+ }
+
+ UidNetdPermissionInfo(int permissions) {
+ mNetdPermissions = permissions;
+ }
+
+ /** Plus given permissions and return new UidNetdPermissionInfo instance. */
+ public UidNetdPermissionInfo plusNetdPermissions(int permissions) {
+ return new UidNetdPermissionInfo(mNetdPermissions | permissions);
+ }
+
+ /** Return whether package is uninstalled. */
+ public boolean isPackageUninstalled() {
+ return mNetdPermissions == PERMISSION_UNINSTALLED;
+ }
+
+ /** Check that uid has given permissions */
+ public boolean hasNetdPermissions(final int permissions) {
+ if (isPackageUninstalled()) return false;
+ if (permissions == PERMISSION_NONE) return true;
+ return (mNetdPermissions & permissions) == permissions;
+ }
+ }
+
+ public PermissionMonitor(Context context, INetd netd) {
this(context, netd, new Dependencies());
}
@@ -161,7 +195,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
return;
}
- SparseIntArray netdPermsUids = new SparseIntArray();
+ final SparseArray<UidNetdPermissionInfo> netdPermsUids = new SparseArray<>();
for (PackageInfo app : apps) {
int uid = app.applicationInfo != null ? app.applicationInfo.uid : INVALID_UID;
@@ -183,9 +217,13 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
}
}
+ // Skip already checked uid.
+ if (netdPermsUids.get(uid) != null) continue;
+
//TODO: unify the management of the permissions into one codepath.
- final int otherNetdPerms = getNetdPermissionMask(uid);
- netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
+ final UidNetdPermissionInfo permInfo =
+ new UidNetdPermissionInfo(getNetdPermissionMask(uid));
+ netdPermsUids.put(uid, permInfo);
}
List<UserInfo> users = mUserManager.getUsers(true); // exclude dying users
@@ -207,7 +245,10 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
? PERMISSION_UPDATE_DEVICE_STATS : 0;
netdPermission |= perms.contains(INTERNET) ? PERMISSION_INTERNET : 0;
}
- netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission);
+ final UidNetdPermissionInfo permInfo = netdPermsUids.get(uid);
+ netdPermsUids.put(uid, permInfo != null
+ ? permInfo.plusNetdPermissions(netdPermission)
+ : new UidNetdPermissionInfo(netdPermission));
}
log("Users: " + mUsers.size() + ", Apps: " + mApps.size());
update(mUsers, mApps, true);
@@ -341,15 +382,15 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
return currentPermission;
}
- private int getPermissionForUid(final int uid) {
+ private UidNetdPermissionInfo getPermissionForUid(final int uid) {
// Check all the packages for this UID. The UID has the permission if any of the
// packages in it has the permission.
final String[] packages = mPackageManager.getPackagesForUid(uid);
if (packages == null || packages.length <= 0) {
// The last package of this uid is removed from device. Clean the package up.
- return PERMISSION_UNINSTALLED;
+ return new UidNetdPermissionInfo(PERMISSION_UNINSTALLED);
}
- return getNetdPermissionMask(uid);
+ return new UidNetdPermissionInfo(getNetdPermissionMask(uid));
}
/**
@@ -599,28 +640,28 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
* permission information to netd.
*
* @param uid the app uid of the package installed
- * @param permissions the permissions the app requested and netd cares about.
+ * @param permissionInfo the permission info of given uid.
*
* @hide
*/
@VisibleForTesting
- void sendPackagePermissionsForUid(int uid, int permissions) {
- SparseIntArray netdPermissionsAppIds = new SparseIntArray();
- netdPermissionsAppIds.put(uid, permissions);
- sendPackagePermissionsToNetd(netdPermissionsAppIds);
+ void sendPackagePermissionsForUid(int uid, UidNetdPermissionInfo permissionInfo) {
+ final SparseArray<UidNetdPermissionInfo> uidsPermInfo = new SparseArray<>();
+ uidsPermInfo.put(uid, permissionInfo);
+ sendPackagePermissionsToNetd(uidsPermInfo);
}
/**
* Called by packageManagerService to send IPC to netd. Grant or revoke the INTERNET
* and/or UPDATE_DEVICE_STATS permission of the uids in array.
*
- * @param netdPermissionsAppIds integer pairs of uids and the permission granted to it. If the
- * permission is 0, revoke all permissions of that uid.
- *
+ * @param uidsPermInfo permission info array generated from each uid. If the uid permission is
+ * PERMISSION_NONE or PERMISSION_UNINSTALLED, revoke all permissions of that
+ * uid.
* @hide
*/
@VisibleForTesting
- void sendPackagePermissionsToNetd(SparseIntArray netdPermissionsAppIds) {
+ void sendPackagePermissionsToNetd(final SparseArray<UidNetdPermissionInfo> uidsPermInfo) {
if (mNetd == null) {
Log.e(TAG, "Failed to get the netd service");
return;
@@ -630,26 +671,20 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
ArrayList<Integer> updateStatsPermissionAppIds = new ArrayList<>();
ArrayList<Integer> noPermissionAppIds = new ArrayList<>();
ArrayList<Integer> uninstalledAppIds = new ArrayList<>();
- for (int i = 0; i < netdPermissionsAppIds.size(); i++) {
- int permissions = netdPermissionsAppIds.valueAt(i);
- switch(permissions) {
- case (PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS):
- allPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
- break;
- case PERMISSION_INTERNET:
- internetPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
- break;
- case PERMISSION_UPDATE_DEVICE_STATS:
- updateStatsPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
- break;
- case PERMISSION_NONE:
- noPermissionAppIds.add(netdPermissionsAppIds.keyAt(i));
- break;
- case PERMISSION_UNINSTALLED:
- uninstalledAppIds.add(netdPermissionsAppIds.keyAt(i));
- default:
- Log.e(TAG, "unknown permission type: " + permissions + "for uid: "
- + netdPermissionsAppIds.keyAt(i));
+ for (int i = 0; i < uidsPermInfo.size(); i++) {
+ final int uid = uidsPermInfo.keyAt(i);
+ final UidNetdPermissionInfo permInfo = uidsPermInfo.valueAt(i);
+ if (permInfo.hasNetdPermissions(
+ PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS)) {
+ allPermissionAppIds.add(uid);
+ } else if (permInfo.hasNetdPermissions(PERMISSION_INTERNET)) {
+ internetPermissionAppIds.add(uid);
+ } else if (permInfo.hasNetdPermissions(PERMISSION_UPDATE_DEVICE_STATS)) {
+ updateStatsPermissionAppIds.add(uid);
+ } else if (permInfo.isPackageUninstalled()) {
+ uninstalledAppIds.add(uid);
+ } else {
+ noPermissionAppIds.add(uid);
}
}
try {
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 1c93d4eb599b..5484bfca5851 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -153,8 +153,8 @@ public class Vpn {
private static final boolean LOGD = true;
// Length of time (in milliseconds) that an app hosting an always-on VPN is placed on
- // the device idle whitelist during service launch and VPN bootstrap.
- private static final long VPN_LAUNCH_IDLE_WHITELIST_DURATION_MS = 60 * 1000;
+ // the device idle allowlist during service launch and VPN bootstrap.
+ private static final long VPN_LAUNCH_IDLE_ALLOWLIST_DURATION_MS = 60 * 1000;
// Settings for how much of the address space should be routed so that Vpn considers
// "most" of the address space is routed. This is used to determine whether this Vpn
@@ -180,7 +180,8 @@ public class Vpn {
// This is taken as a total of IPv4 + IPV6 routes for simplicity, but the algorithm
// is actually O(n²)+O(n²).
private static final int MAX_ROUTES_TO_EVALUATE = 150;
-
+ private static final String LOCKDOWN_ALLOWLIST_SETTING_NAME =
+ Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST;
/**
* Largest profile size allowable for Platform VPNs.
*
@@ -236,7 +237,7 @@ public class Vpn {
* Set of packages in addition to the VPN app itself that can access the network directly when
* VPN is not connected even if {@code mLockdown} is set.
*/
- private @NonNull List<String> mLockdownWhitelist = Collections.emptyList();
+ private @NonNull List<String> mLockdownAllowlist = Collections.emptyList();
/**
* A memory of what UIDs this class told netd to block for the lockdown feature.
@@ -520,7 +521,7 @@ public class Vpn {
}
}
if (!hadUnderlyingNetworks) {
- // No idea what the underlying networks are; assume sane defaults
+ // No idea what the underlying networks are; assume the safer defaults
metered = true;
roaming = false;
congested = false;
@@ -653,18 +654,18 @@ public class Vpn {
*
* @param packageName the package to designate as always-on VPN supplier.
* @param lockdown whether to prevent traffic outside of a VPN, for example while connecting.
- * @param lockdownWhitelist packages to be whitelisted from lockdown.
+ * @param lockdownAllowlist packages to be allowed from lockdown.
* @param keyStore the Keystore instance to use for checking of PlatformVpnProfile(s)
* @return {@code true} if the package has been set as always-on, {@code false} otherwise.
*/
public synchronized boolean setAlwaysOnPackage(
@Nullable String packageName,
boolean lockdown,
- @Nullable List<String> lockdownWhitelist,
+ @Nullable List<String> lockdownAllowlist,
@NonNull KeyStore keyStore) {
enforceControlPermissionOrInternalCaller();
- if (setAlwaysOnPackageInternal(packageName, lockdown, lockdownWhitelist, keyStore)) {
+ if (setAlwaysOnPackageInternal(packageName, lockdown, lockdownAllowlist, keyStore)) {
saveAlwaysOnPackage();
return true;
}
@@ -679,7 +680,7 @@ public class Vpn {
*
* @param packageName the package to designate as always-on VPN supplier.
* @param lockdown whether to prevent traffic outside of a VPN, for example while connecting.
- * @param lockdownWhitelist packages to be whitelisted from lockdown. This is only used if
+ * @param lockdownAllowlist packages to be allowed to bypass lockdown. This is only used if
* {@code lockdown} is {@code true}. Packages must not contain commas.
* @param keyStore the system keystore instance to check for profiles
* @return {@code true} if the package has been set as always-on, {@code false} otherwise.
@@ -687,16 +688,16 @@ public class Vpn {
@GuardedBy("this")
private boolean setAlwaysOnPackageInternal(
@Nullable String packageName, boolean lockdown,
- @Nullable List<String> lockdownWhitelist, @NonNull KeyStore keyStore) {
+ @Nullable List<String> lockdownAllowlist, @NonNull KeyStore keyStore) {
if (VpnConfig.LEGACY_VPN.equals(packageName)) {
Log.w(TAG, "Not setting legacy VPN \"" + packageName + "\" as always-on.");
return false;
}
- if (lockdownWhitelist != null) {
- for (String pkg : lockdownWhitelist) {
+ if (lockdownAllowlist != null) {
+ for (String pkg : lockdownAllowlist) {
if (pkg.contains(",")) {
- Log.w(TAG, "Not setting always-on vpn, invalid whitelisted package: " + pkg);
+ Log.w(TAG, "Not setting always-on vpn, invalid allowed package: " + pkg);
return false;
}
}
@@ -724,8 +725,8 @@ public class Vpn {
}
mLockdown = (mAlwaysOn && lockdown);
- mLockdownWhitelist = (mLockdown && lockdownWhitelist != null)
- ? Collections.unmodifiableList(new ArrayList<>(lockdownWhitelist))
+ mLockdownAllowlist = (mLockdown && lockdownAllowlist != null)
+ ? Collections.unmodifiableList(new ArrayList<>(lockdownAllowlist))
: Collections.emptyList();
if (isCurrentPreparedPackage(packageName)) {
@@ -754,10 +755,10 @@ public class Vpn {
}
/**
- * @return an immutable list of packages whitelisted from always-on VPN lockdown.
+ * @return an immutable list of packages allowed to bypass always-on VPN lockdown.
*/
- public synchronized List<String> getLockdownWhitelist() {
- return mLockdown ? mLockdownWhitelist : null;
+ public synchronized List<String> getLockdownAllowlist() {
+ return mLockdown ? mLockdownAllowlist : null;
}
/**
@@ -772,8 +773,8 @@ public class Vpn {
mSystemServices.settingsSecurePutIntForUser(Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN,
(mAlwaysOn && mLockdown ? 1 : 0), mUserHandle);
mSystemServices.settingsSecurePutStringForUser(
- Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST,
- String.join(",", mLockdownWhitelist), mUserHandle);
+ LOCKDOWN_ALLOWLIST_SETTING_NAME,
+ String.join(",", mLockdownAllowlist), mUserHandle);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -788,12 +789,12 @@ public class Vpn {
Settings.Secure.ALWAYS_ON_VPN_APP, mUserHandle);
final boolean alwaysOnLockdown = mSystemServices.settingsSecureGetIntForUser(
Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN, 0 /*default*/, mUserHandle) != 0;
- final String whitelistString = mSystemServices.settingsSecureGetStringForUser(
- Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN_WHITELIST, mUserHandle);
- final List<String> whitelistedPackages = TextUtils.isEmpty(whitelistString)
- ? Collections.emptyList() : Arrays.asList(whitelistString.split(","));
+ final String allowlistString = mSystemServices.settingsSecureGetStringForUser(
+ LOCKDOWN_ALLOWLIST_SETTING_NAME, mUserHandle);
+ final List<String> allowedPackages = TextUtils.isEmpty(allowlistString)
+ ? Collections.emptyList() : Arrays.asList(allowlistString.split(","));
setAlwaysOnPackageInternal(
- alwaysOnPackage, alwaysOnLockdown, whitelistedPackages, keyStore);
+ alwaysOnPackage, alwaysOnLockdown, allowedPackages, keyStore);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -849,7 +850,7 @@ public class Vpn {
DeviceIdleInternal idleController =
LocalServices.getService(DeviceIdleInternal.class);
idleController.addPowerSaveTempWhitelistApp(Process.myUid(), alwaysOnPackage,
- VPN_LAUNCH_IDLE_WHITELIST_DURATION_MS, mUserHandle, false, "vpn");
+ VPN_LAUNCH_IDLE_ALLOWLIST_DURATION_MS, mUserHandle, false, "vpn");
// Start the VPN service declared in the app's manifest.
Intent serviceIntent = new Intent(VpnConfig.SERVICE_INTERFACE);
@@ -1212,7 +1213,7 @@ public class Vpn {
// applications have changed. Consider diffing UID ranges and only applying the delta.
if (!Objects.equals(oldConfig.allowedApplications, mConfig.allowedApplications) ||
!Objects.equals(oldConfig.disallowedApplications, mConfig.disallowedApplications)) {
- Log.i(TAG, "Handover not possible due to changes to whitelisted/blacklisted apps");
+ Log.i(TAG, "Handover not possible due to changes to allowed/denied apps");
return false;
}
@@ -1440,13 +1441,13 @@ public class Vpn {
* associated with one user, and any restricted profiles attached to that user.
*
* <p>If one of {@param allowedApplications} or {@param disallowedApplications} is provided,
- * the UID ranges will match the app whitelist or blacklist specified there. Otherwise, all UIDs
+ * the UID ranges will match the app list specified there. Otherwise, all UIDs
* in each user and profile will be included.
*
* @param userHandle The userId to create UID ranges for along with any of its restricted
* profiles.
- * @param allowedApplications (optional) whitelist of applications to include.
- * @param disallowedApplications (optional) blacklist of applications to exclude.
+ * @param allowedApplications (optional) List of applications to allow.
+ * @param disallowedApplications (optional) List of applications to deny.
*/
@VisibleForTesting
Set<UidRange> createUserAndRestrictedProfilesRanges(@UserIdInt int userHandle,
@@ -1480,13 +1481,13 @@ public class Vpn {
* associated with one user.
*
* <p>If one of {@param allowedApplications} or {@param disallowedApplications} is provided,
- * the UID ranges will match the app whitelist or blacklist specified there. Otherwise, all UIDs
+ * the UID ranges will match the app allowlist or denylist specified there. Otherwise, all UIDs
* in the user will be included.
*
* @param ranges {@link Set} of {@link UidRange}s to which to add.
* @param userHandle The userId to add to {@param ranges}.
- * @param allowedApplications (optional) whitelist of applications to include.
- * @param disallowedApplications (optional) blacklist of applications to exclude.
+ * @param allowedApplications (optional) allowlist of applications to include.
+ * @param disallowedApplications (optional) denylist of applications to exclude.
*/
@VisibleForTesting
void addUserToRanges(@NonNull Set<UidRange> ranges, @UserIdInt int userHandle,
@@ -1608,7 +1609,7 @@ public class Vpn {
/**
* Restricts network access from all UIDs affected by this {@link Vpn}, apart from the VPN
- * service app itself and whitelisted packages, to only sockets that have had {@code protect()}
+ * service app itself and allowed packages, to only sockets that have had {@code protect()}
* called on them. All non-VPN traffic is blocked via a {@code PROHIBIT} response from the
* kernel.
*
@@ -1630,7 +1631,7 @@ public class Vpn {
if (isNullOrLegacyVpn(mPackage)) {
exemptedPackages = null;
} else {
- exemptedPackages = new ArrayList<>(mLockdownWhitelist);
+ exemptedPackages = new ArrayList<>(mLockdownAllowlist);
exemptedPackages.add(mPackage);
}
final Set<UidRange> rangesToTellNetdToRemove = new ArraySet<>(mBlockedUidsAsToldToNetd);
@@ -1675,7 +1676,7 @@ public class Vpn {
* Tell netd to add or remove a list of {@link UidRange}s to the list of UIDs that are only
* allowed to make connections through sockets that have had {@code protect()} called on them.
*
- * @param enforce {@code true} to add to the blacklist, {@code false} to remove.
+ * @param enforce {@code true} to add to the denylist, {@code false} to remove.
* @param ranges {@link Collection} of {@link UidRange}s to add (if {@param enforce} is
* {@code true}) or to remove.
* @return {@code true} if all of the UIDs were added/removed. {@code false} otherwise,
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
index 05cf40a091b6..3ac95d71de3d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
@@ -178,7 +178,7 @@ public abstract class InputMethodManagerInternal {
};
/**
- * @return Global instance if exists. Otherwise, a dummy no-op instance.
+ * @return Global instance if exists. Otherwise, a fallback no-op instance.
*/
@NonNull
public static InputMethodManagerInternal get() {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 3cd70fecbf3d..9ab410d258cc 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2213,8 +2213,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* @param client {@link android.os.Binder} proxy that is associated with the singleton instance
* of {@link android.view.inputmethod.InputMethodManager} that runs on the client
* process
- * @param inputContext communication channel for the dummy
- * {@link android.view.inputmethod.InputConnection}
+ * @param inputContext communication channel for the fallback {@link InputConnection}
* @param selfReportedDisplayId self-reported display ID to which the client is associated.
* Whether the client is still allowed to access to this display
* or not needs to be evaluated every time the client interacts
@@ -3451,9 +3450,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return InputBindResult.USER_SWITCHING;
}
- // Master feature flag that overrides other conditions and forces IME preRendering.
+ // Main feature flag that overrides other conditions and forces IME preRendering.
if (DEBUG) {
- Slog.v(TAG, "IME PreRendering MASTER flag: "
+ Slog.v(TAG, "IME PreRendering main flag: "
+ DebugFlags.FLAG_PRE_RENDER_IME_VIEWS.value() + ", LowRam: " + mIsLowRam);
}
// pre-rendering not supported on low-ram devices.
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 937514ca9139..b518eb1ab6d0 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -1663,7 +1663,7 @@ public final class MultiClientInputMethodManagerService {
}
if (editorInfo == null) {
- // So-called dummy InputConnection scenario. For app compatibility, we still
+ // So-called fallback InputConnection scenario. For app compatibility, we still
// notify this to the IME.
switch (clientInfo.mState) {
case InputMethodClientState.READY_TO_SEND_FIRST_BIND_RESULT:
diff --git a/services/core/java/com/android/server/location/LocationProviderManager.java b/services/core/java/com/android/server/location/LocationProviderManager.java
index c3532a84c42d..05aa3150cfef 100644
--- a/services/core/java/com/android/server/location/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/LocationProviderManager.java
@@ -229,7 +229,7 @@ class LocationProviderManager extends
// we cache these values because checking/calculating on the fly is more expensive
private boolean mPermitted;
private boolean mForeground;
- @Nullable private LocationRequest mProviderLocationRequest;
+ private LocationRequest mProviderLocationRequest;
private boolean mIsUsingHighPower;
protected Registration(LocationRequest request, CallerIdentity identity,
@@ -244,6 +244,8 @@ class LocationProviderManager extends
} else {
mWorkSource = identity.addToWorkSource(null);
}
+
+ mProviderLocationRequest = super.getRequest();
}
@GuardedBy("mLock")
@@ -313,7 +315,7 @@ class LocationProviderManager extends
@Override
public final LocationRequest getRequest() {
- return Objects.requireNonNull(mProviderLocationRequest);
+ return mProviderLocationRequest;
}
public final boolean isForeground() {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
index 81d07cc11527..e9a05a8aa16c 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -484,7 +484,7 @@ class LockSettingsStorage {
public Map<Integer, List<Long>> listSyntheticPasswordHandlesForAllUsers(String stateName) {
Map<Integer, List<Long>> result = new ArrayMap<>();
final UserManager um = UserManager.get(mContext);
- for (UserInfo user : um.getUsers(false)) {
+ for (UserInfo user : um.getUsers()) {
result.put(user.id, listSyntheticPasswordHandlesForUser(stateName, user.id));
}
return result;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 0f6748366e16..8777ceacf884 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -589,11 +589,19 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
if (mDestroyed) {
return;
}
+ ParceledListSlice<QueueItem> parcelableQueue;
+ if (mQueue == null) {
+ parcelableQueue = null;
+ } else {
+ parcelableQueue = new ParceledListSlice<>(mQueue);
+ // Limit the size of initial Parcel to prevent binder buffer overflow
+ // as onQueueChanged is an async binder call.
+ parcelableQueue.setInlineCountLimit(1);
+ }
for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
try {
- holder.mCallback.onQueueChanged(mQueue == null ? null :
- new ParceledListSlice<>(mQueue));
+ holder.mCallback.onQueueChanged(parcelableQueue);
} catch (DeadObjectException e) {
mControllerCallbackHolders.remove(i);
logCallbackException("Removing dead callback in pushQueueUpdate", holder, e);
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index eb4ab1ceac28..a8a0e2e937d0 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -32,14 +32,15 @@ import android.app.KeyguardManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.UserInfo;
-import android.database.ContentObserver;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
import android.media.AudioPlaybackConfiguration;
@@ -58,7 +59,6 @@ import android.media.session.ISessionManager;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
-import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -138,7 +138,6 @@ public class MediaSessionService extends SystemService implements Monitor {
private KeyguardManager mKeyguardManager;
private AudioManagerInternal mAudioManagerInternal;
private ContentResolver mContentResolver;
- private SettingsObserver mSettingsObserver;
private boolean mHasFeatureLeanback;
// The FullUserRecord of the current users. (i.e. The foreground user that isn't a profile)
@@ -192,8 +191,6 @@ public class MediaSessionService extends SystemService implements Monitor {
}
}, null /* handler */);
mContentResolver = mContext.getContentResolver();
- mSettingsObserver = new SettingsObserver();
- mSettingsObserver.observe();
mHasFeatureLeanback = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_LEANBACK);
@@ -202,8 +199,20 @@ public class MediaSessionService extends SystemService implements Monitor {
instantiateCustomProvider(null);
instantiateCustomDispatcher(null);
mRecordThread.start();
+
+ final IntentFilter filter = new IntentFilter(
+ NotificationManager.ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED);
+ mContext.registerReceiver(mNotificationListenerEnabledChangedReceiver, filter);
}
+ private final BroadcastReceiver mNotificationListenerEnabledChangedReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ updateActiveSessionListeners();
+ }
+ };
+
private boolean isGlobalPriorityActiveLocked() {
return mGlobalPrioritySession != null && mGlobalPrioritySession.isActive();
}
@@ -1082,25 +1091,6 @@ public class MediaSessionService extends SystemService implements Monitor {
}
}
- final class SettingsObserver extends ContentObserver {
- private final Uri mSecureSettingsUri = Settings.Secure.getUriFor(
- Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
-
- private SettingsObserver() {
- super(null);
- }
-
- private void observe() {
- mContentResolver.registerContentObserver(mSecureSettingsUri,
- false, this, ALL.getIdentifier());
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- updateActiveSessionListeners();
- }
- }
-
class SessionManagerImpl extends ISessionManager.Stub {
private static final String EXTRA_WAKELOCK_ACQUIRED =
"android.media.AudioService.WAKELOCK_ACQUIRED";
@@ -2710,5 +2700,4 @@ public class MediaSessionService extends SystemService implements Monitor {
obtainMessage(msg, userIdInteger).sendToTarget();
}
}
-
}
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index 953aae44d6a7..d9b5b6d41c11 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -20,7 +20,6 @@ import static com.android.server.media.SessionPolicyProvider.SESSION_POLICY_IGNO
import android.media.Session2Token;
import android.media.session.MediaSession;
-import android.os.Debug;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
@@ -187,7 +186,7 @@ class MediaSessionStack {
*/
public void updateMediaButtonSessionIfNeeded() {
if (DEBUG) {
- Log.d(TAG, "updateMediaButtonSessionIfNeeded, callers=" + Debug.getCallers(2));
+ Log.d(TAG, "updateMediaButtonSessionIfNeeded, callers=" + getCallers(2));
}
List<Integer> audioPlaybackUids =
mAudioPlayerStateMonitor.getSortedAudioPlaybackClientUids();
@@ -413,4 +412,24 @@ class MediaSessionStack {
// so they also need to be cleared.
mCachedActiveLists.remove(UserHandle.USER_ALL);
}
+
+ // Code copied from android.os.Debug#getCallers(int)
+ private static String getCallers(final int depth) {
+ final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < depth; i++) {
+ sb.append(getCaller(callStack, i)).append(" ");
+ }
+ return sb.toString();
+ }
+
+ // Code copied from android.os.Debug#getCaller(StackTraceElement[], int)
+ private static String getCaller(StackTraceElement[] callStack, int depth) {
+ // callStack[4] is the caller of the method that called getCallers()
+ if (4 + depth >= callStack.length) {
+ return "<bottom of call stack>";
+ }
+ StackTraceElement caller = callStack[4 + depth];
+ return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 2d052da22714..9f9235dc852f 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -31,6 +31,7 @@ import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED
import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL;
import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED;
import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED;
+import static android.app.NotificationManager.ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED;
import static android.app.NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
import static android.app.NotificationManager.EXTRA_AUTOMATIC_ZEN_RULE_ID;
@@ -7758,6 +7759,13 @@ public class NotificationManagerService extends SystemService {
@VisibleForTesting
void updateUriPermissions(@Nullable NotificationRecord newRecord,
@Nullable NotificationRecord oldRecord, String targetPkg, int targetUserId) {
+ updateUriPermissions(newRecord, oldRecord, targetPkg, targetUserId, false);
+ }
+
+ @VisibleForTesting
+ void updateUriPermissions(@Nullable NotificationRecord newRecord,
+ @Nullable NotificationRecord oldRecord, String targetPkg, int targetUserId,
+ boolean onlyRevokeCurrentTarget) {
final String key = (newRecord != null) ? newRecord.getKey() : oldRecord.getKey();
if (DBG) Slog.d(TAG, key + ": updating permissions");
@@ -7785,7 +7793,9 @@ public class NotificationManagerService extends SystemService {
}
// If we have no Uris to grant, but an existing owner, go destroy it
- if (newUris == null && permissionOwner != null) {
+ // When revoking permissions of a single listener, destroying the owner will revoke
+ // permissions of other listeners who need to keep access.
+ if (newUris == null && permissionOwner != null && !onlyRevokeCurrentTarget) {
destroyPermissionOwner(permissionOwner, UserHandle.getUserId(oldRecord.getUid()), key);
permissionOwner = null;
}
@@ -7808,9 +7818,20 @@ public class NotificationManagerService extends SystemService {
final Uri uri = oldUris.valueAt(i);
if (newUris == null || !newUris.contains(uri)) {
if (DBG) Slog.d(TAG, key + ": revoking " + uri);
- int userId = ContentProvider.getUserIdFromUri(
- uri, UserHandle.getUserId(oldRecord.getUid()));
- revokeUriPermission(permissionOwner, uri, userId);
+ if (onlyRevokeCurrentTarget) {
+ // We're revoking permission from one listener only; other listeners may
+ // still need access because the notification may still exist
+ revokeUriPermission(permissionOwner, uri,
+ UserHandle.getUserId(oldRecord.getUid()), targetPkg, targetUserId);
+ } else {
+ // This is broad to unilaterally revoke permissions to this Uri as granted
+ // by this notification. But this code-path can only be used when the
+ // reason for revoking is that the notification posted again without this
+ // Uri, not when removing an individual listener.
+ revokeUriPermission(permissionOwner, uri,
+ UserHandle.getUserId(oldRecord.getUid()),
+ null, UserHandle.USER_ALL);
+ }
}
}
}
@@ -7839,8 +7860,10 @@ public class NotificationManagerService extends SystemService {
}
}
- private void revokeUriPermission(IBinder owner, Uri uri, int userId) {
+ private void revokeUriPermission(IBinder owner, Uri uri, int sourceUserId, String targetPkg,
+ int targetUserId) {
if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return;
+ int userId = ContentProvider.getUserIdFromUri(uri, sourceUserId);
final long ident = Binder.clearCallingIdentity();
try {
@@ -7848,7 +7871,7 @@ public class NotificationManagerService extends SystemService {
owner,
ContentProvider.getUriWithoutUserId(uri),
Intent.FLAG_GRANT_READ_URI_PERMISSION,
- userId);
+ userId, targetPkg, targetUserId);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -9158,6 +9181,17 @@ public class NotificationManagerService extends SystemService {
}
@Override
+ protected void setPackageOrComponentEnabled(String pkgOrComponent, int userId,
+ boolean isPrimary, boolean enabled) {
+ super.setPackageOrComponentEnabled(pkgOrComponent, userId, isPrimary, enabled);
+
+ getContext().sendBroadcastAsUser(
+ new Intent(ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
+ UserHandle.ALL, null);
+ }
+
+ @Override
protected void loadDefaultsFromConfig() {
String defaultListenerAccess = mContext.getResources().getString(
R.string.config_defaultListenerAccessPackages);
@@ -9219,6 +9253,7 @@ public class NotificationManagerService extends SystemService {
final NotificationRankingUpdate update;
synchronized (mNotificationLock) {
update = makeRankingUpdateLocked(info);
+ updateUriPermissionsForActiveNotificationsLocked(info, true);
}
try {
listener.onListenerConnected(update);
@@ -9230,6 +9265,7 @@ public class NotificationManagerService extends SystemService {
@Override
@GuardedBy("mNotificationLock")
protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
+ updateUriPermissionsForActiveNotificationsLocked(removed, false);
if (removeDisabledHints(removed)) {
updateListenerHintsLocked();
updateEffectsSuppressorLocked();
@@ -9296,8 +9332,7 @@ public class NotificationManagerService extends SystemService {
for (final ManagedServiceInfo info : getServices()) {
boolean sbnVisible = isVisibleToListener(sbn, info);
- boolean oldSbnVisible = oldSbn != null ? isVisibleToListener(oldSbn, info)
- : false;
+ boolean oldSbnVisible = (oldSbn != null) && isVisibleToListener(oldSbn, info);
// This notification hasn't been and still isn't visible -> ignore.
if (!oldSbnVisible && !sbnVisible) {
continue;
@@ -9321,13 +9356,8 @@ public class NotificationManagerService extends SystemService {
// This notification became invisible -> remove the old one.
if (oldSbnVisible && !sbnVisible) {
final StatusBarNotification oldSbnLightClone = oldSbn.cloneLight();
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- notifyRemoved(
- info, oldSbnLightClone, update, null, REASON_USER_STOPPED);
- }
- });
+ mHandler.post(() -> notifyRemoved(
+ info, oldSbnLightClone, update, null, REASON_USER_STOPPED));
continue;
}
@@ -9337,12 +9367,7 @@ public class NotificationManagerService extends SystemService {
updateUriPermissions(r, old, info.component.getPackageName(), targetUserId);
final StatusBarNotification sbnToPost = trimCache.ForListener(info);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- notifyPosted(info, sbnToPost, update);
- }
- });
+ mHandler.post(() -> notifyPosted(info, sbnToPost, update));
}
} catch (Exception e) {
Slog.e(TAG, "Could not notify listeners for " + r.getKey(), e);
@@ -9350,6 +9375,46 @@ public class NotificationManagerService extends SystemService {
}
/**
+ * Synchronously grant or revoke permissions to Uris for all active and visible
+ * notifications to just the NotificationListenerService provided.
+ */
+ @GuardedBy("mNotificationLock")
+ private void updateUriPermissionsForActiveNotificationsLocked(
+ ManagedServiceInfo info, boolean grant) {
+ try {
+ for (final NotificationRecord r : mNotificationList) {
+ // When granting permissions, ignore notifications which are invisible.
+ // When revoking permissions, all notifications are invisible, so process all.
+ if (grant && !isVisibleToListener(r.getSbn(), info)) {
+ continue;
+ }
+ // If the notification is hidden, permissions are not required by the listener.
+ if (r.isHidden() && info.targetSdkVersion < Build.VERSION_CODES.P) {
+ continue;
+ }
+ // Grant or revoke access synchronously
+ final int targetUserId = (info.userid == UserHandle.USER_ALL)
+ ? UserHandle.USER_SYSTEM : info.userid;
+ if (grant) {
+ // Grant permissions by passing arguments as if the notification is new.
+ updateUriPermissions(/* newRecord */ r, /* oldRecord */ null,
+ info.component.getPackageName(), targetUserId);
+ } else {
+ // Revoke permissions by passing arguments as if the notification was
+ // removed, but set `onlyRevokeCurrentTarget` to avoid revoking permissions
+ // granted to *other* targets by this notification's URIs.
+ updateUriPermissions(/* newRecord */ null, /* oldRecord */ r,
+ info.component.getPackageName(), targetUserId,
+ /* onlyRevokeCurrentTarget */ true);
+ }
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "Could not " + (grant ? "grant" : "revoke") + " Uri permissions to "
+ + info.component, e);
+ }
+ }
+
+ /**
* asynchronously notify all listeners about a removed notification
*/
@GuardedBy("mNotificationLock")
@@ -9384,18 +9449,11 @@ public class NotificationManagerService extends SystemService {
final NotificationStats stats = mAssistants.isServiceTokenValidLocked(info.service)
? notificationStats : null;
final NotificationRankingUpdate update = makeRankingUpdateLocked(info);
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- notifyRemoved(info, sbnLight, update, stats, reason);
- }
- });
+ mHandler.post(() -> notifyRemoved(info, sbnLight, update, stats, reason));
}
// Revoke access after all listeners have been updated
- mHandler.post(() -> {
- updateUriPermissions(null, r, null, UserHandle.USER_SYSTEM);
- });
+ mHandler.post(() -> updateUriPermissions(null, r, null, UserHandle.USER_SYSTEM));
}
/**
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 840645edcb82..8af74631fb2e 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -613,6 +613,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
throw new IllegalArgumentException(
"APEX files can only be installed as part of a staged session.");
}
+ if (params.isMultiPackage) {
+ throw new IllegalArgumentException("A multi-session can't be set as APEX.");
+ }
}
if (params.isStaged && !isCalledBySystemOrShell(callingUid)) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index ff9edd511e84..bc090f0aadda 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1328,12 +1328,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
if (PackageInstaller.STATUS_SUCCESS == status) {
mChildSessionsRemaining.removeAt(sessionIndex);
if (mChildSessionsRemaining.size() == 0) {
- try {
- intent.putExtra(PackageInstaller.EXTRA_SESSION_ID,
- PackageInstallerSession.this.sessionId);
- mStatusReceiver.sendIntent(mContext, 0, intent, null, null);
- } catch (IntentSender.SendIntentException ignore) {
- }
+ destroyInternal();
+ dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED,
+ "Session installed", null);
}
} else if (PackageInstaller.STATUS_PENDING_USER_ACTION == status) {
try {
@@ -1492,53 +1489,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
/**
- * Assert multipackage install has consistent sessions.
- *
- * @throws PackageManagerException if child sessions don't match parent session
- * in respect to staged and enable rollback parameters.
- */
- @GuardedBy("mLock")
- private void assertMultiPackageConsistencyLocked(
- @NonNull List<PackageInstallerSession> childSessions) throws PackageManagerException {
- for (PackageInstallerSession childSession : childSessions) {
- // It might be that the parent session is loaded before all of it's child sessions are,
- // e.g. when reading sessions from XML. Those sessions will be null here, and their
- // conformance with the multipackage params will be checked when they're loaded.
- if (childSession == null) {
- continue;
- }
- assertConsistencyWithLocked(childSession);
- }
- }
-
- /**
- * Assert consistency with the given session.
- *
- * @throws PackageManagerException if other sessions doesn't match this session
- * in respect to staged and enable rollback parameters.
- */
- @GuardedBy("mLock")
- private void assertConsistencyWithLocked(PackageInstallerSession other)
- throws PackageManagerException {
- // Session groups must be consistent wrt to isStaged parameter. Non-staging session
- // cannot be grouped with staging sessions.
- if (this.params.isStaged != other.params.isStaged) {
- throw new PackageManagerException(
- PackageManager.INSTALL_FAILED_MULTIPACKAGE_INCONSISTENCY,
- "Multipackage Inconsistency: session " + other.sessionId
- + " and session " + sessionId
- + " have inconsistent staged settings");
- }
- if (this.params.getEnableRollback() != other.params.getEnableRollback()) {
- throw new PackageManagerException(
- PackageManager.INSTALL_FAILED_MULTIPACKAGE_INCONSISTENCY,
- "Multipackage Inconsistency: session " + other.sessionId
- + " and session " + sessionId
- + " have inconsistent rollback settings");
- }
- }
-
- /**
* Seal the session to prevent further modification.
*
* <p>The session will be sealed after calling this method even if it failed.
@@ -1552,14 +1502,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
try {
assertNoWriteFileTransfersOpenLocked();
assertPreparedAndNotDestroyedLocked("sealing of session");
-
mSealed = true;
- List<PackageInstallerSession> childSessions = getChildSessionsLocked();
- if (childSessions != null) {
- assertMultiPackageConsistencyLocked(childSessions);
- }
- } catch (PackageManagerException e) {
- throw onSessionValidationFailure(e);
} catch (Throwable e) {
// Convert all exceptions into package manager exceptions as only those are handled
// in the code above.
@@ -1637,7 +1580,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
* If session should be sealed, then it's sealed to prevent further modification.
* If the session can't be sealed then it's destroyed.
*
- * Additionally for staged APEX sessions read+validate the package and populate req'd fields.
+ * Additionally for staged APEX/APK sessions read+validate the package and populate req'd
+ * fields.
*
* <p> This is meant to be called after all of the sessions are loaded and added to
* PackageInstallerService
@@ -1670,6 +1614,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
// APEX installations rely on certain fields to be populated after reboot.
// E.g. mPackageName.
validateApexInstallLocked();
+ } else {
+ // Populate mPackageName for this APK session which is required by the staging
+ // manager to check duplicate apk-in-apex.
+ PackageInstallerSession parent = allSessions.get(mParentSessionId);
+ if (parent != null && parent.isStagedSessionReady()) {
+ validateApkInstallLocked();
+ }
}
} catch (PackageManagerException e) {
Slog.e(TAG, "Package not valid", e);
@@ -3185,6 +3136,16 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
throw new IllegalStateException("Multi-session " + childSessionId
+ " can't be a child.");
}
+ if (params.isStaged != childSession.params.isStaged) {
+ throw new IllegalStateException("Multipackage Inconsistency: session "
+ + childSession.sessionId + " and session " + sessionId
+ + " have inconsistent staged settings");
+ }
+ if (params.getEnableRollback() != childSession.params.getEnableRollback()) {
+ throw new IllegalStateException("Multipackage Inconsistency: session "
+ + childSession.sessionId + " and session " + sessionId
+ + " have inconsistent rollback settings");
+ }
try {
acquireTransactionLock();
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0d1c00dfe035..b96aaf4abd08 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17591,9 +17591,6 @@ public class PackageManagerService extends IPackageManager.Stub
synchronized (mLock) {
pkgSetting = mSettings.getPackageLPr(pkgName);
}
- String abiOverride =
- (pkgSetting == null || TextUtils.isEmpty(pkgSetting.cpuAbiOverrideString)
- ? args.abiOverride : pkgSetting.cpuAbiOverrideString);
boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null
&& pkgSetting.getPkgState().isUpdatedSystemApp();
AndroidPackage oldPackage = mPackages.get(pkgName);
@@ -17601,7 +17598,7 @@ public class PackageManagerService extends IPackageManager.Stub
final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
derivedAbi = mInjector.getAbiHelper().derivePackageAbi(parsedPackage,
isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
- abiOverride);
+ args.abiOverride);
derivedAbi.first.applyTo(parsedPackage);
derivedAbi.second.applyTo(parsedPackage);
} catch (PackageManagerException pme) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 3e3e3c590491..3e253673ad31 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4647,6 +4647,9 @@ public final class Settings {
pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.getCodePathString());
pw.print(prefix); pw.print(" legacyNativeLibraryDir=");
pw.println(ps.legacyNativeLibraryPathString);
+ pw.print(prefix); pw.print(" extractNativeLibs=");
+ pw.println((ps.pkgFlags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0
+ ? "true" : "false");
pw.print(prefix); pw.print(" primaryCpuAbi="); pw.println(ps.primaryCpuAbiString);
pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
}
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index f9bf54a11df0..ac05aabf998f 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -56,6 +56,7 @@ import android.os.UserManagerInternal;
import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
@@ -84,6 +85,7 @@ import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@@ -650,6 +652,7 @@ public class StagingManager {
try {
if (hasApex) {
checkInstallationOfApkInApexSuccessful(session);
+ checkDuplicateApkInApex(session);
snapshotAndRestoreForApexSession(session);
Slog.i(TAG, "APEX packages in session " + session.sessionId
+ " were successfully activated. Proceeding with APK packages, if any");
@@ -829,6 +832,40 @@ public class StagingManager {
return null;
}
+ /**
+ * Throws a PackageManagerException if there are duplicate packages in apk and apk-in-apex.
+ */
+ private void checkDuplicateApkInApex(@NonNull PackageInstallerSession session)
+ throws PackageManagerException {
+ if (!session.isMultiPackage()) {
+ return;
+ }
+ final int[] childSessionIds = session.getChildSessionIds();
+ final Set<String> apkNames = new ArraySet<>();
+ synchronized (mStagedSessions) {
+ for (int id : childSessionIds) {
+ final PackageInstallerSession s = mStagedSessions.get(id);
+ if (!isApexSession(s)) {
+ apkNames.add(s.getPackageName());
+ }
+ }
+ }
+ final List<PackageInstallerSession> apexSessions = extractApexSessions(session);
+ for (PackageInstallerSession apexSession : apexSessions) {
+ String packageName = apexSession.getPackageName();
+ for (String apkInApex : mApexManager.getApksInApex(packageName)) {
+ if (!apkNames.add(apkInApex)) {
+ throw new PackageManagerException(
+ SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
+ "Package: " + packageName + " in session: "
+ + apexSession.sessionId + " has duplicate apk-in-apex: "
+ + apkInApex, null);
+
+ }
+ }
+ }
+ }
+
private void installApksInSession(@NonNull PackageInstallerSession session)
throws PackageManagerException {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index f66b4ee5a1a7..d137fd05f793 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -499,20 +499,23 @@ public class UserManagerService extends IUserManager.Stub {
states = new SparseIntArray();
invalidateIsUserUnlockedCache();
}
- public int get(int userId) {
+ public int get(@UserIdInt int userId) {
return states.get(userId);
}
- public int get(int userId, int fallback) {
+ public int get(@UserIdInt int userId, int fallback) {
return states.indexOfKey(userId) >= 0 ? states.get(userId) : fallback;
}
- public void put(int userId, int state) {
+ public void put(@UserIdInt int userId, int state) {
states.put(userId, state);
invalidateIsUserUnlockedCache();
}
- public void delete(int userId) {
+ public void delete(@UserIdInt int userId) {
states.delete(userId);
invalidateIsUserUnlockedCache();
}
+ public boolean has(@UserIdInt int userId) {
+ return states.get(userId, UserHandle.USER_NULL) != UserHandle.USER_NULL;
+ }
@Override
public String toString() {
return states.toString();
@@ -3561,6 +3564,13 @@ public class UserManagerService extends IUserManager.Stub {
if (preCreatedUserData == null) {
return null;
}
+ synchronized (mUserStates) {
+ if (mUserStates.has(preCreatedUserData.info.id)) {
+ Slog.w(LOG_TAG, "Cannot reuse pre-created user "
+ + preCreatedUserData.info.id + " because it didn't stop yet");
+ return null;
+ }
+ }
final UserInfo preCreatedUser = preCreatedUserData.info;
final int newFlags = preCreatedUser.flags | flags;
if (!checkUserTypeConsistency(newFlags)) {
@@ -5225,6 +5235,7 @@ public class UserManagerService extends IUserManager.Stub {
return userData == null ? null : userData.info;
}
+ @Override
public @NonNull UserInfo[] getUserInfos() {
synchronized (mUsersLock) {
int userSize = mUsers.size();
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 63aa80e8269a..3d1570476b48 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -881,7 +881,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
@Override
- public int checkPermission(String permName, String pkgName, int userId) {
+ public int checkPermission(String permName, String pkgName, @UserIdInt int userId) {
// Not using Objects.requireNonNull() here for compatibility reasons.
if (permName == null || pkgName == null) {
return PackageManager.PERMISSION_DENIED;
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 4d48a2e63b30..ae2b040d0a89 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -89,7 +89,7 @@ import java.util.concurrent.ExecutionException;
public final class PermissionPolicyService extends SystemService {
private static final String LOG_TAG = PermissionPolicyService.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final long USER_SENSITIVE_UPDATE_DELAY_MS = 10000;
+ private static final long USER_SENSITIVE_UPDATE_DELAY_MS = 60000;
private final Object mLock = new Object();
@@ -283,6 +283,11 @@ public final class PermissionPolicyService extends SystemService {
manager.updateUserSensitiveForApp(uid);
}
}, UserHandle.ALL, intentFilter, null, null);
+
+ PermissionControllerManager manager = new PermissionControllerManager(
+ getUserContext(getContext(), Process.myUserHandle()), FgThread.getHandler());
+ FgThread.getHandler().postDelayed(manager::updateUserSensitive,
+ USER_SENSITIVE_UPDATE_DELAY_MS);
}
/**
@@ -425,8 +430,7 @@ public final class PermissionPolicyService extends SystemService {
throw new IllegalStateException(e);
}
- FgThread.getHandler().postDelayed(permissionControllerManager::updateUserSensitive,
- USER_SENSITIVE_UPDATE_DELAY_MS);
+ permissionControllerManager.updateUserSensitive();
packageManagerInternal.updateRuntimePermissionsFingerprint(userId);
}
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index ef4954aa4e4c..ae0db4419080 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -200,7 +200,7 @@ public class ThermalManagerService extends SystemService {
final int count = mTemperatureMap.size();
for (int i = 0; i < count; i++) {
Temperature t = mTemperatureMap.valueAt(i);
- if (t.getStatus() >= newStatus) {
+ if (t.getType() == Temperature.TYPE_SKIN && t.getStatus() >= newStatus) {
newStatus = t.getStatus();
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index b3ec849e6c90..8ccbbdd2265c 100755
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -99,6 +99,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -1177,7 +1178,8 @@ public final class TvInputManagerService extends SystemService {
final int resolvedUserId = resolveCallingUserId(callingPid, callingUid,
userId, "createSession");
final long identity = Binder.clearCallingIdentity();
- StringBuilder sessionId = new StringBuilder();
+ // Generate a unique session id with a random UUID.
+ String uniqueSessionId = UUID.randomUUID().toString();
try {
synchronized (mLock) {
if (userId != mCurrentUserId && !isRecordingSession) {
@@ -1206,20 +1208,17 @@ public final class TvInputManagerService extends SystemService {
return;
}
- // Create a unique session id with pid, uid and resolved user id
- sessionId.append(callingUid).append(callingPid).append(resolvedUserId);
-
// Create a new session token and a session state.
IBinder sessionToken = new Binder();
SessionState sessionState = new SessionState(sessionToken, info.getId(),
info.getComponent(), isRecordingSession, client, seq, callingUid,
- callingPid, resolvedUserId, sessionId.toString());
+ callingPid, resolvedUserId, uniqueSessionId);
// Add them to the global session state map of the current user.
userState.sessionStateMap.put(sessionToken, sessionState);
// Map the session id to the sessionStateMap in the user state
- mSessionIdToSessionStateMap.put(sessionId.toString(), sessionState);
+ mSessionIdToSessionStateMap.put(uniqueSessionId, sessionState);
// Also, add them to the session state map of the current service.
serviceState.sessionTokens.add(sessionToken);
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
index 2b0fe8a2602b..2fc17fe65775 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/ClientProfile.java
@@ -68,6 +68,11 @@ public final class ClientProfile {
private Set<Integer> mUsingFrontendIds = new HashSet<>();
/**
+ * List of the client ids that share frontend with the current client.
+ */
+ private Set<Integer> mShareFeClientIds = new HashSet<>();
+
+ /**
* List of the Lnb ids that are used by the current client.
*/
private Set<Integer> mUsingLnbIds = new HashSet<>();
@@ -113,11 +118,7 @@ public final class ClientProfile {
}
public int getPriority() {
- return mPriority;
- }
-
- public int getNiceValue() {
- return mNiceValue;
+ return mPriority - mNiceValue;
}
public void setGroupId(int groupId) {
@@ -141,17 +142,38 @@ public final class ClientProfile {
mUsingFrontendIds.add(frontendId);
}
+ /**
+ * Update the set of client that share frontend with the current client.
+ *
+ * @param clientId the client to share the fe with the current client.
+ */
+ public void shareFrontend(int clientId) {
+ mShareFeClientIds.add(clientId);
+ }
+
+ /**
+ * Remove the given client id from the share frontend client id set.
+ *
+ * @param clientId the client to stop sharing the fe with the current client.
+ */
+ public void stopSharingFrontend(int clientId) {
+ mShareFeClientIds.remove(clientId);
+ }
+
public Set<Integer> getInUseFrontendIds() {
return mUsingFrontendIds;
}
+ public Set<Integer> getShareFeClientIds() {
+ return mShareFeClientIds;
+ }
+
/**
* Called when the client released a frontend.
- *
- * @param frontendId being released.
*/
- public void releaseFrontend(int frontendId) {
- mUsingFrontendIds.remove(frontendId);
+ public void releaseFrontend() {
+ mUsingFrontendIds.clear();
+ mShareFeClientIds.clear();
}
/**
@@ -201,6 +223,7 @@ public final class ClientProfile {
*/
public void reclaimAllResources() {
mUsingFrontendIds.clear();
+ mShareFeClientIds.clear();
mUsingLnbIds.clear();
mUsingCasSystemId = INVALID_RESOURCE_ID;
}
diff --git a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
index 7cb59dcbfb9b..fb2347e8e133 100644
--- a/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
+++ b/services/core/java/com/android/server/tv/tunerresourcemanager/TunerResourceManagerService.java
@@ -210,19 +210,36 @@ public class TunerResourceManagerService extends SystemService implements IBinde
}
synchronized (mLock) {
if (!checkClientExists(request.getClientId())) {
- throw new RemoteException("Request frontend from unregistered client:"
+ throw new RemoteException("Request frontend from unregistered client: "
+ request.getClientId());
}
+ // If the request client is holding or sharing a frontend, throw an exception.
+ if (!getClientProfile(request.getClientId()).getInUseFrontendIds().isEmpty()) {
+ throw new RemoteException("Release frontend before requesting another one. "
+ + "Client id: " + request.getClientId());
+ }
return requestFrontendInternal(request, frontendHandle);
}
}
@Override
- public void shareFrontend(int selfClientId, int targetClientId) {
+ public void shareFrontend(int selfClientId, int targetClientId) throws RemoteException {
enforceTunerAccessPermission("shareFrontend");
enforceTrmAccessPermission("shareFrontend");
- if (DEBUG) {
- Slog.d(TAG, "shareFrontend from " + selfClientId + " with " + targetClientId);
+ synchronized (mLock) {
+ if (!checkClientExists(selfClientId)) {
+ throw new RemoteException("Share frontend request from an unregistered client:"
+ + selfClientId);
+ }
+ if (!checkClientExists(targetClientId)) {
+ throw new RemoteException("Request to share frontend with an unregistered "
+ + "client:" + targetClientId);
+ }
+ if (getClientProfile(targetClientId).getInUseFrontendIds().isEmpty()) {
+ throw new RemoteException("Request to share frontend with a client that has no "
+ + "frontend resources. Target client id:" + targetClientId);
+ }
+ shareFrontendInternal(selfClientId, targetClientId);
}
}
@@ -315,7 +332,7 @@ public class TunerResourceManagerService extends SystemService implements IBinde
throw new RemoteException(
"Client is not the current owner of the releasing fe.");
}
- releaseFrontendInternal(fe);
+ releaseFrontendInternal(fe, clientId);
}
}
@@ -649,6 +666,17 @@ public class TunerResourceManagerService extends SystemService implements IBinde
}
@VisibleForTesting
+ protected void shareFrontendInternal(int selfClientId, int targetClientId) {
+ if (DEBUG) {
+ Slog.d(TAG, "shareFrontend from " + selfClientId + " with " + targetClientId);
+ }
+ for (int feId : getClientProfile(targetClientId).getInUseFrontendIds()) {
+ getClientProfile(selfClientId).useFrontend(feId);
+ }
+ getClientProfile(targetClientId).shareFrontend(selfClientId);
+ }
+
+ @VisibleForTesting
protected boolean requestLnbInternal(TunerLnbRequest request, int[] lnbHandle) {
if (DEBUG) {
Slog.d(TAG, "requestLnb(request=" + request + ")");
@@ -777,11 +805,17 @@ public class TunerResourceManagerService extends SystemService implements IBinde
}
@VisibleForTesting
- protected void releaseFrontendInternal(FrontendResource fe) {
+ protected void releaseFrontendInternal(FrontendResource fe, int clientId) {
if (DEBUG) {
- Slog.d(TAG, "releaseFrontend(id=" + fe.getId() + ")");
+ Slog.d(TAG, "releaseFrontend(id=" + fe.getId() + ", clientId=" + clientId + " )");
+ }
+ if (clientId == fe.getOwnerClientId()) {
+ ClientProfile ownerClient = getClientProfile(fe.getOwnerClientId());
+ for (int shareOwnerId : ownerClient.getShareFeClientIds()) {
+ clearFrontendAndClientMapping(getClientProfile(shareOwnerId));
+ }
}
- updateFrontendClientMappingOnRelease(fe);
+ clearFrontendAndClientMapping(getClientProfile(clientId));
}
@VisibleForTesting
@@ -882,8 +916,21 @@ public class TunerResourceManagerService extends SystemService implements IBinde
Slog.e(TAG, "Failed to reclaim resources on client " + reclaimingClientId, e);
return false;
}
+
+ // Reclaim all the resources of the share owners of the frontend that is used by the current
+ // resource reclaimed client.
ClientProfile profile = getClientProfile(reclaimingClientId);
- reclaimingResourcesFromClient(profile);
+ Set<Integer> shareFeClientIds = profile.getShareFeClientIds();
+ for (int clientId : shareFeClientIds) {
+ try {
+ mListeners.get(clientId).getListener().onReclaimResources();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to reclaim resources on client " + clientId, e);
+ return false;
+ }
+ clearAllResourcesAndClientMapping(getClientProfile(clientId));
+ }
+ clearAllResourcesAndClientMapping(profile);
return true;
}
@@ -929,16 +976,6 @@ public class TunerResourceManagerService extends SystemService implements IBinde
}
}
- private void updateFrontendClientMappingOnRelease(@NonNull FrontendResource releasingFrontend) {
- ClientProfile ownerProfile = getClientProfile(releasingFrontend.getOwnerClientId());
- releasingFrontend.removeOwner();
- ownerProfile.releaseFrontend(releasingFrontend.getId());
- for (int exclusiveGroupMember : releasingFrontend.getExclusiveGroupMemberFeIds()) {
- getFrontendResource(exclusiveGroupMember).removeOwner();
- ownerProfile.releaseFrontend(exclusiveGroupMember);
- }
- }
-
private void updateLnbClientMappingOnNewGrant(int grantingId, int ownerClientId) {
LnbResource grantingLnb = getLnbResource(grantingId);
ClientProfile ownerProfile = getClientProfile(ownerClientId);
@@ -967,10 +1004,10 @@ public class TunerResourceManagerService extends SystemService implements IBinde
}
/**
- * Get the owner client's priority from the resource id.
+ * Get the owner client's priority.
*
* @param clientId the owner client id.
- * @return the priority of the owner client of the resource.
+ * @return the priority of the owner client.
*/
private int getOwnerClientPriority(int clientId) {
return getClientProfile(clientId).getPriority();
@@ -1011,7 +1048,11 @@ public class TunerResourceManagerService extends SystemService implements IBinde
return;
}
if (fe.isInUse()) {
- releaseFrontendInternal(fe);
+ ClientProfile ownerClient = getClientProfile(fe.getOwnerClientId());
+ for (int shareOwnerId : ownerClient.getShareFeClientIds()) {
+ clearFrontendAndClientMapping(getClientProfile(shareOwnerId));
+ }
+ clearFrontendAndClientMapping(ownerClient);
}
for (int excGroupmemberFeId : fe.getExclusiveGroupMemberFeIds()) {
getFrontendResource(excGroupmemberFeId)
@@ -1093,21 +1134,37 @@ public class TunerResourceManagerService extends SystemService implements IBinde
}
private void removeClientProfile(int clientId) {
- reclaimingResourcesFromClient(getClientProfile(clientId));
+ for (int shareOwnerId : getClientProfile(clientId).getShareFeClientIds()) {
+ clearFrontendAndClientMapping(getClientProfile(shareOwnerId));
+ }
+ clearAllResourcesAndClientMapping(getClientProfile(clientId));
mClientProfiles.remove(clientId);
mListeners.remove(clientId);
}
- private void reclaimingResourcesFromClient(ClientProfile profile) {
+ private void clearFrontendAndClientMapping(ClientProfile profile) {
for (Integer feId : profile.getInUseFrontendIds()) {
- getFrontendResource(feId).removeOwner();
+ FrontendResource fe = getFrontendResource(feId);
+ if (fe.getOwnerClientId() == profile.getId()) {
+ fe.removeOwner();
+ continue;
+ }
+ getClientProfile(fe.getOwnerClientId()).stopSharingFrontend(profile.getId());
}
+ profile.releaseFrontend();
+ }
+
+ private void clearAllResourcesAndClientMapping(ClientProfile profile) {
+ // Clear Lnb
for (Integer lnbId : profile.getInUseLnbIds()) {
getLnbResource(lnbId).removeOwner();
}
+ // Clear Cas
if (profile.getInUseCasSystemId() != ClientProfile.INVALID_RESOURCE_ID) {
getCasResource(profile.getInUseCasSystemId()).removeOwner(profile.getId());
}
+ // Clear Frontend
+ clearFrontendAndClientMapping(profile);
profile.reclaimAllResources();
}
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java b/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java
index cdb61995c336..5772dea287fc 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerInternal.java
@@ -75,10 +75,31 @@ public interface UriGrantsManagerInternal {
void removeUriPermissionsForPackage(
String packageName, int userHandle, boolean persistable, boolean targetOnly);
/**
- * @param uri This uri must NOT contain an embedded userId.
+ * Remove any {@link UriPermission} associated with the owner whose values match the given
+ * filtering parameters.
+ *
+ * @param token An opaque owner token as returned by {@link #newUriPermissionOwner(String)}.
+ * @param uri This uri must NOT contain an embedded userId. {@code null} to apply to all Uris.
+ * @param mode The modes (as a bitmask) to revoke.
* @param userId The userId in which the uri is to be resolved.
*/
void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId);
+
+ /**
+ * Remove any {@link UriPermission} associated with the owner whose values match the given
+ * filtering parameters.
+ *
+ * @param token An opaque owner token as returned by {@link #newUriPermissionOwner(String)}.
+ * @param uri This uri must NOT contain an embedded userId. {@code null} to apply to all Uris.
+ * @param mode The modes (as a bitmask) to revoke.
+ * @param userId The userId in which the uri is to be resolved.
+ * @param targetPkg Calling package name to match, or {@code null} to apply to all packages.
+ * @param targetUserId Calling user to match, or {@link UserHandle#USER_ALL} to apply to all
+ * users.
+ */
+ void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId,
+ String targetPkg, int targetUserId);
+
boolean checkAuthorityGrants(
int callingUid, ProviderInfo cpi, int userId, boolean checkUser);
void dump(PrintWriter pw, boolean dumpAll, String dumpPackage);
diff --git a/services/core/java/com/android/server/uri/UriGrantsManagerService.java b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
index f5e1602ee6be..a106dc682208 100644
--- a/services/core/java/com/android/server/uri/UriGrantsManagerService.java
+++ b/services/core/java/com/android/server/uri/UriGrantsManagerService.java
@@ -51,7 +51,6 @@ import android.app.AppGlobals;
import android.app.GrantedUriPermission;
import android.app.IUriGrantsManager;
import android.content.ClipData;
-import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
@@ -88,11 +87,11 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
-import libcore.io.IoUtils;
-
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
+import libcore.io.IoUtils;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -1431,16 +1430,18 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub {
@Override
public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
+ revokeUriPermissionFromOwner(token, uri, mode, userId, null, UserHandle.USER_ALL);
+ }
+
+ @Override
+ public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId,
+ String targetPkg, int targetUserId) {
final UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
if (owner == null) {
throw new IllegalArgumentException("Unknown owner: " + token);
}
-
- if (uri == null) {
- owner.removeUriPermissions(mode);
- } else {
- owner.removeUriPermission(new GrantUri(userId, uri, mode), mode);
- }
+ GrantUri grantUri = uri == null ? null : new GrantUri(userId, uri, mode);
+ owner.removeUriPermission(grantUri, mode, targetPkg, targetUserId);
}
@Override
diff --git a/services/core/java/com/android/server/uri/UriPermissionOwner.java b/services/core/java/com/android/server/uri/UriPermissionOwner.java
index 2b404a43a338..0c263997a8b5 100644
--- a/services/core/java/com/android/server/uri/UriPermissionOwner.java
+++ b/services/core/java/com/android/server/uri/UriPermissionOwner.java
@@ -21,6 +21,7 @@ import static android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
import android.os.Binder;
import android.os.IBinder;
+import android.os.UserHandle;
import android.util.ArraySet;
import android.util.proto.ProtoOutputStream;
@@ -74,30 +75,47 @@ public class UriPermissionOwner {
}
void removeUriPermission(GrantUri grantUri, int mode) {
+ removeUriPermission(grantUri, mode, null, UserHandle.USER_ALL);
+ }
+
+ void removeUriPermission(GrantUri grantUri, int mode, String targetPgk, int targetUserId) {
if ((mode & FLAG_GRANT_READ_URI_PERMISSION) != 0 && mReadPerms != null) {
Iterator<UriPermission> it = mReadPerms.iterator();
while (it.hasNext()) {
UriPermission perm = it.next();
- if (grantUri == null || grantUri.equals(perm.uri)) {
- perm.removeReadOwner(this);
- mService.removeUriPermissionIfNeeded(perm);
- it.remove();
+ if (grantUri != null && !grantUri.equals(perm.uri)) {
+ continue;
+ }
+ if (targetPgk != null && !targetPgk.equals(perm.targetPkg)) {
+ continue;
}
+ if (targetUserId != UserHandle.USER_ALL && targetUserId != perm.targetUserId) {
+ continue;
+ }
+ perm.removeReadOwner(this);
+ mService.removeUriPermissionIfNeeded(perm);
+ it.remove();
}
if (mReadPerms.isEmpty()) {
mReadPerms = null;
}
}
- if ((mode & FLAG_GRANT_WRITE_URI_PERMISSION) != 0
- && mWritePerms != null) {
+ if ((mode & FLAG_GRANT_WRITE_URI_PERMISSION) != 0 && mWritePerms != null) {
Iterator<UriPermission> it = mWritePerms.iterator();
while (it.hasNext()) {
UriPermission perm = it.next();
- if (grantUri == null || grantUri.equals(perm.uri)) {
- perm.removeWriteOwner(this);
- mService.removeUriPermissionIfNeeded(perm);
- it.remove();
+ if (grantUri != null && !grantUri.equals(perm.uri)) {
+ continue;
+ }
+ if (targetPgk != null && !targetPgk.equals(perm.targetPkg)) {
+ continue;
+ }
+ if (targetUserId != UserHandle.USER_ALL && targetUserId != perm.targetUserId) {
+ continue;
}
+ perm.removeWriteOwner(this);
+ mService.removeUriPermissionIfNeeded(perm);
+ it.remove();
}
if (mWritePerms.isEmpty()) {
mWritePerms = null;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 5b8078729eee..e4f28546a5fd 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2549,7 +2549,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final Task stack = getRootTask();
final boolean mayAdjustTop = (isState(RESUMED) || stack.mResumedActivity == null)
- && stack.isFocusedStackOnDisplay();
+ && stack.isFocusedStackOnDisplay()
+ // Do not adjust focus task because the task will be reused to launch new activity.
+ && !task.isClearingToReuseTask();
final boolean shouldAdjustGlobalFocus = mayAdjustTop
// It must be checked before {@link #makeFinishingLocked} is called, because a stack
// is not visible if it only contains finishing activities.
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index f7cb0146ea52..15e88fc44746 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2023,8 +2023,6 @@ class ActivityStarter {
// of history or if it is finished immediately), thus disassociating the task. Also note
// that mReuseTask is reset as a result of {@link Task#performClearTaskLocked}
// launching another activity.
- // TODO(b/36119896): We shouldn't trigger activity launches in this path since we are
- // already launching one.
targetTask.performClearTaskLocked();
targetTask.setIntent(mStartActivity);
mAddingToTask = true;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 31a9c5d4242c..8204b36bc551 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -251,7 +251,6 @@ import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.AttributeCache;
import com.android.server.LocalServices;
import com.android.server.SystemService;
-import com.android.server.SystemService.TargetUser;
import com.android.server.SystemServiceManager;
import com.android.server.UiThread;
import com.android.server.Watchdog;
@@ -5347,15 +5346,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return mAmInternal.isBackgroundActivityStartsEnabled();
}
- void enableScreenAfterBoot(boolean booted) {
- writeBootProgressEnableScreen(SystemClock.uptimeMillis());
- mWindowManager.enableScreenAfterBoot();
-
- synchronized (mGlobalLock) {
- updateEventDispatchingLocked(booted);
- }
- }
-
static long getInputDispatchingTimeoutMillisLocked(ActivityRecord r) {
if (r == null || !r.hasProcess()) {
return DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
@@ -6449,9 +6439,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public void enableScreenAfterBoot(boolean booted) {
+ writeBootProgressEnableScreen(SystemClock.uptimeMillis());
+ mWindowManager.enableScreenAfterBoot();
synchronized (mGlobalLock) {
- writeBootProgressEnableScreen(SystemClock.uptimeMillis());
- mWindowManager.enableScreenAfterBoot();
updateEventDispatchingLocked(booted);
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ba5a38290349..affbafa095cc 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1557,7 +1557,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// the heavy operations. This also benefits that the states of multiple activities
// are handled together.
r.linkFixedRotationTransform(prevRotatedLaunchingApp);
- setFixedRotationLaunchingAppUnchecked(r, rotation);
+ if (r != mFixedRotationTransitionListener.mAnimatingRecents) {
+ // Only update the record for normal activity so the display orientation can be
+ // updated when the transition is done if it becomes the top. And the case of
+ // recents can be handled when the recents animation is finished.
+ setFixedRotationLaunchingAppUnchecked(r, rotation);
+ }
return;
}
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index df5356303f8b..3c64ffb237d6 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -1627,8 +1627,8 @@ class RecentTasks {
}
if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: adding affilliates starting at "
+ topIndex + " from intial " + taskIndex);
- // Find the end of the chain, doing a sanity check along the way.
- boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
+ // Find the end of the chain, doing a validity check along the way.
+ boolean isValid = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
int endIndex = topIndex;
Task prev = top;
while (endIndex < recentsCount) {
@@ -1640,7 +1640,7 @@ class RecentTasks {
if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
Slog.wtf(TAG, "Bad chain @" + endIndex
+ ": first task has next affiliate: " + prev);
- sane = false;
+ isValid = false;
break;
}
} else {
@@ -1652,7 +1652,7 @@ class RecentTasks {
+ " has bad next affiliate "
+ cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
+ ", expected " + prev);
- sane = false;
+ isValid = false;
break;
}
}
@@ -1662,7 +1662,7 @@ class RecentTasks {
Slog.wtf(TAG, "Bad chain @" + endIndex
+ ": last task " + cur + " has previous affiliate "
+ cur.mPrevAffiliate);
- sane = false;
+ isValid = false;
}
if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "addRecent: end of chain @" + endIndex);
break;
@@ -1673,7 +1673,7 @@ class RecentTasks {
+ ": task " + cur + " has previous affiliate "
+ cur.mPrevAffiliate + " but should be id "
+ cur.mPrevAffiliate);
- sane = false;
+ isValid = false;
break;
}
}
@@ -1682,7 +1682,7 @@ class RecentTasks {
+ ": task " + cur + " has affiliated id "
+ cur.mAffiliatedTaskId + " but should be "
+ task.mAffiliatedTaskId);
- sane = false;
+ isValid = false;
break;
}
prev = cur;
@@ -1690,18 +1690,18 @@ class RecentTasks {
if (endIndex >= recentsCount) {
Slog.wtf(TAG, "Bad chain ran off index " + endIndex
+ ": last task " + prev);
- sane = false;
+ isValid = false;
break;
}
}
- if (sane) {
+ if (isValid) {
if (endIndex < taskIndex) {
Slog.wtf(TAG, "Bad chain @" + endIndex
+ ": did not extend to task " + task + " @" + taskIndex);
- sane = false;
+ isValid = false;
}
}
- if (sane) {
+ if (isValid) {
// All looks good, we can just move all of the affiliated tasks
// to the top.
for (int i=topIndex; i<=endIndex; i++) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index b3a3ed7eeba4..fe2d08f6a4c2 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -737,7 +737,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
winAnimator.mSession.mPid, operation);
final long callingIdentity = Binder.clearCallingIdentity();
try {
- // There was some problem...first, do a sanity check of the window list to make sure
+ // There was some problem...first, do a validity check of the window list to make sure
// we haven't left any dangling surfaces around.
Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
@@ -811,7 +811,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
// "Something has changed! Let's make it correct now."
- // TODO: Super crazy long method that should be broken down...
+ // TODO: Super long method that should be broken down...
void performSurfacePlacementNoTrace() {
if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
+ Debug.getCallers(3));
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index ec7b1eed7f91..0529abf89f6e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1836,14 +1836,25 @@ class Task extends WindowContainer<WindowContainer> {
*/
void performClearTaskLocked() {
mReuseTask = true;
- performClearTask("clear-task-all");
- mReuseTask = false;
+ mStackSupervisor.beginDeferResume();
+ try {
+ performClearTask("clear-task-all");
+ } finally {
+ mStackSupervisor.endDeferResume();
+ mReuseTask = false;
+ }
}
ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
mReuseTask = true;
- final ActivityRecord result = performClearTaskLocked(newR, launchFlags);
- mReuseTask = false;
+ mStackSupervisor.beginDeferResume();
+ final ActivityRecord result;
+ try {
+ result = performClearTaskLocked(newR, launchFlags);
+ } finally {
+ mStackSupervisor.endDeferResume();
+ mReuseTask = false;
+ }
return result;
}
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 68445f6970fb..dbbb7ff69b3b 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -27,7 +27,6 @@ import android.annotation.Nullable;
import android.app.ActivityManager.TaskSnapshot;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
-import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.RecordingCanvas;
@@ -82,7 +81,7 @@ class TaskSnapshotController {
/**
* Return value for {@link #getSnapshotMode}: We are not allowed to take a real screenshot but
- * we should try to use the app theme to create a dummy representation of the app.
+ * we should try to use the app theme to create a fake representation of the app.
*/
@VisibleForTesting
static final int SNAPSHOT_MODE_APP_THEME = 1;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index b33a8e9ef5df..7624d4c1ea36 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3612,7 +3612,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG_WM, ">>> showStrictModeViolation");
- // TODO: Modify this to use the surface trace once it is not going crazy.
+ // TODO: Modify this to use the surface trace once it is not going baffling.
// b/31532461
// TODO(multi-display): support multiple displays
if (mStrictModeFlash == null) {
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index ab6e35b452a0..c714eeb92e68 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -196,7 +196,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
private final Configuration mLastReportedConfiguration = new Configuration();
// Configuration that is waiting to be dispatched to the process.
private Configuration mPendingConfiguration;
- private final Configuration mNewOverrideConfig = new Configuration();
// Registered display id as a listener to override config change
private int mDisplayId;
private ActivityRecord mConfigActivityRecord;
@@ -1292,11 +1291,26 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
}
@Override
+ public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
+ super.onRequestedOverrideConfigurationChanged(
+ sanitizeProcessConfiguration(overrideConfiguration));
+ }
+
+ @Override
public void onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfig) {
+ super.onRequestedOverrideConfigurationChanged(
+ sanitizeProcessConfiguration(mergedOverrideConfig));
+ }
+
+ private static Configuration sanitizeProcessConfiguration(Configuration config) {
// Make sure that we don't accidentally override the activity type.
- mNewOverrideConfig.setTo(mergedOverrideConfig);
- mNewOverrideConfig.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED);
- super.onRequestedOverrideConfigurationChanged(mNewOverrideConfig);
+ if (config.windowConfiguration.getActivityType() != ACTIVITY_TYPE_UNDEFINED) {
+ final Configuration sanitizedConfig = new Configuration(config);
+ sanitizedConfig.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED);
+ return sanitizedConfig;
+ }
+
+ return config;
}
private void updateConfiguration() {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ebbd74aa7d1e..49e623d8dd11 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2456,9 +2456,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
finishInputEvent(event, true);
}
}
- /**
- * Dummy event receiver for windows that died visible.
- */
+ /** Fake event receiver for windows that died visible. */
private DeadWindowEventReceiver mDeadWindowEventReceiver;
void openInputChannel(InputChannel outInputChannel) {
@@ -2476,9 +2474,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mClientChannel.dispose();
mClientChannel = null;
} else {
- // If the window died visible, we setup a dummy input channel, so that taps
+ // If the window died visible, we setup a fake input channel, so that taps
// can still detected by input monitor channel, and we can relaunch the app.
- // Create dummy event receiver that simply reports all events as handled.
+ // Create fake event receiver that simply reports all events as handled.
mDeadWindowEventReceiver = new DeadWindowEventReceiver(mClientChannel);
}
mWmService.mInputToWindowMap.put(mInputWindowHandle.token, this);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 16edb55939a3..92177abbbf85 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -560,9 +560,9 @@ class WindowStateAnimator {
}
}
- // Something is wrong and SurfaceFlinger will not like this, try to revert to sane values.
- // This doesn't necessarily mean that there is an error in the system. The sizes might be
- // incorrect, because it is before the first layout or draw.
+ // Something is wrong and SurfaceFlinger will not like this, try to revert to reasonable
+ // values. This doesn't necessarily mean that there is an error in the system. The sizes
+ // might be incorrect, because it is before the first layout or draw.
if (outSize.width() < 1) {
outSize.right = 1;
}
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index f7cd37fb6748..bc4d9a973ecb 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -548,7 +548,7 @@ class WindowToken extends WindowContainer<WindowState> {
void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames,
Configuration config) {
if (mFixedRotationTransformState != null) {
- return;
+ cleanUpFixedRotationTransformState(true /* replacing */);
}
mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames,
new Configuration(config), mDisplayContent.getRotation());
@@ -565,13 +565,13 @@ class WindowToken extends WindowContainer<WindowState> {
* one. This takes the same effect as {@link #applyFixedRotationTransform}.
*/
void linkFixedRotationTransform(WindowToken other) {
- if (mFixedRotationTransformState != null) {
- return;
- }
final FixedRotationTransformState fixedRotationState = other.mFixedRotationTransformState;
- if (fixedRotationState == null) {
+ if (fixedRotationState == null || mFixedRotationTransformState == fixedRotationState) {
return;
}
+ if (mFixedRotationTransformState != null) {
+ cleanUpFixedRotationTransformState(true /* replacing */);
+ }
mFixedRotationTransformState = fixedRotationState;
fixedRotationState.mAssociatedTokens.add(this);
onConfigurationChanged(getParent().getConfiguration());
@@ -626,11 +626,17 @@ class WindowToken extends WindowContainer<WindowState> {
// The state is cleared at the end, because it is used to indicate that other windows can
// use seamless rotation when applying rotation to display.
for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) {
- state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState();
+ state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState(
+ false /* replacing */);
}
}
- private void cleanUpFixedRotationTransformState() {
+ private void cleanUpFixedRotationTransformState(boolean replacing) {
+ if (replacing && mFixedRotationTransformState.mAssociatedTokens.size() > 1) {
+ // The state is not only used by self. Make sure to leave the influence by others.
+ mFixedRotationTransformState.mAssociatedTokens.remove(this);
+ mFixedRotationTransformState.mRotatedContainers.remove(this);
+ }
mFixedRotationTransformState = null;
notifyFixedRotationTransform(false /* enabled */);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/CallerIdentity.java b/services/devicepolicy/java/com/android/server/devicepolicy/CallerIdentity.java
new file mode 100644
index 000000000000..5193fa85d238
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/CallerIdentity.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.os.UserHandle;
+
+/**
+ * Caller identity containing the caller's UID, package name and component name.
+ * All parameters are verified on object creation unless the component name is null and the
+ * caller is a delegate.
+ */
+class CallerIdentity {
+
+ private final int mUid;
+ @Nullable
+ private final String mPackageName;
+ @Nullable
+ private final ComponentName mComponentName;
+
+ CallerIdentity(int uid, @Nullable String packageName, @Nullable ComponentName componentName) {
+ mUid = uid;
+ mPackageName = packageName;
+ mComponentName = componentName;
+ }
+
+ public int getUid() {
+ return mUid;
+ }
+
+ public int getUserId() {
+ return UserHandle.getUserId(mUid);
+ }
+
+ public UserHandle getUserHandle() {
+ return UserHandle.getUserHandleForUid(mUid);
+ }
+
+ @Nullable public String getPackageName() {
+ return mPackageName;
+ }
+
+ @Nullable public ComponentName getComponentName() {
+ return mComponentName;
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index cafd56e5198b..2ab629bf725a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1564,6 +1564,39 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
/**
+ * Creates a new {@link CallerIdentity} object to represent the caller's identity.
+ */
+ private CallerIdentity getCallerIdentity(String callerPackage) {
+ final int callerUid = mInjector.binderGetCallingUid();
+
+ if (!isCallingFromPackage(callerPackage, callerUid)) {
+ throw new SecurityException(
+ String.format("Caller with uid %d is not %s", callerUid, callerPackage));
+ }
+
+ return new CallerIdentity(callerUid, callerPackage, null);
+ }
+
+ /**
+ * Creates a new {@link CallerIdentity} object to represent the caller's identity.
+ */
+ private CallerIdentity getCallerIdentity(@NonNull ComponentName componentName) {
+ final int callerUid = mInjector.binderGetCallingUid();
+ final DevicePolicyData policy = getUserData(UserHandle.getUserId(callerUid));
+ ActiveAdmin admin = policy.mAdminMap.get(componentName);
+
+ if (admin == null) {
+ throw new SecurityException(String.format("No active admin for %s", componentName));
+ }
+ if (admin.getUid() != callerUid) {
+ throw new SecurityException(
+ String.format("Admin %s is not owned by uid %d", componentName, callerUid));
+ }
+
+ return new CallerIdentity(callerUid, componentName.getPackageName(), componentName);
+ }
+
+ /**
* Checks if the device is in COMP mode, and if so migrates it to managed profile on a
* corporate owned device.
*/
@@ -7171,6 +7204,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
}
}
+ private boolean isDeviceOwner(CallerIdentity identity) {
+ synchronized (getLockObject()) {
+ return mOwners.hasDeviceOwner()
+ && mOwners.getDeviceOwnerUserId() == identity.getUserId()
+ && mOwners.getDeviceOwnerComponent().equals(identity.getComponentName());
+ }
+ }
+
private boolean isDeviceOwnerPackage(String packageName, int userId) {
synchronized (getLockObject()) {
return mOwners.hasDeviceOwner()
@@ -10427,20 +10468,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
@Override
public void setLocationEnabled(ComponentName who, boolean locationEnabled) {
- enforceDeviceOwner(Objects.requireNonNull(who));
-
- UserHandle user = mInjector.binderGetCallingUserHandle();
+ CallerIdentity identity = getCallerIdentity(who);
+ Preconditions.checkCallAuthorization(isDeviceOwner(identity));
mInjector.binderWithCleanCallingIdentity(() -> {
boolean wasLocationEnabled = mInjector.getLocationManager().isLocationEnabledForUser(
- user);
- mInjector.getLocationManager().setLocationEnabledForUser(locationEnabled, user);
+ identity.getUserHandle());
+ mInjector.getLocationManager().setLocationEnabledForUser(locationEnabled,
+ identity.getUserHandle());
// make a best effort to only show the notification if the admin is actually enabling
// location. this is subject to race conditions with settings changes, but those are
// unlikely to realistically interfere
- if (locationEnabled && (wasLocationEnabled != locationEnabled)) {
- showLocationSettingsEnabledNotification(user);
+ if (locationEnabled && !wasLocationEnabled) {
+ showLocationSettingsEnabledNotification(identity.getUserHandle());
}
});
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 6a797f31fa55..03dce4c62fe8 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -32,7 +32,6 @@ import static android.util.DebugUtils.valueToString;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.server.am.ActivityManagerInternalTest.CustomThread;
-import static com.android.server.am.ActivityManagerService.DISPATCH_UIDS_CHANGED_UI_MSG;
import static com.android.server.am.ActivityManagerService.Injector;
import static com.android.server.am.ProcessList.NETWORK_STATE_BLOCK;
import static com.android.server.am.ProcessList.NETWORK_STATE_NO_CHANGE;
@@ -548,10 +547,10 @@ public class ActivityManagerServiceTest {
pendingChange.processState = procStatesForPendingUidRecords[i];
pendingChange.procStateSeq = i;
changeItems.put(changesForPendingUidRecords[i], pendingChange);
- mAms.mPendingUidChanges.add(pendingChange);
+ mAms.mUidObserverController.mPendingUidChanges.add(pendingChange);
}
- mAms.dispatchUidsChanged();
+ mAms.mUidObserverController.dispatchUidsChanged();
// Verify the required changes have been dispatched to observers.
for (int i = 0; i < observers.length; ++i) {
final int changeToObserve = changesToObserve[i];
@@ -647,8 +646,8 @@ public class ActivityManagerServiceTest {
changeItem.change = UidRecord.CHANGE_PROCSTATE;
changeItem.processState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
changeItem.procStateSeq = 111;
- mAms.mPendingUidChanges.add(changeItem);
- mAms.dispatchUidsChanged();
+ mAms.mUidObserverController.mPendingUidChanges.add(changeItem);
+ mAms.mUidObserverController.dispatchUidsChanged();
// First process state message is always delivered regardless of whether the process state
// change is above or below the cutpoint (PROCESS_STATE_SERVICE).
verify(observer).onUidStateChanged(TEST_UID,
@@ -657,15 +656,15 @@ public class ActivityManagerServiceTest {
verifyNoMoreInteractions(observer);
changeItem.processState = ActivityManager.PROCESS_STATE_RECEIVER;
- mAms.mPendingUidChanges.add(changeItem);
- mAms.dispatchUidsChanged();
+ mAms.mUidObserverController.mPendingUidChanges.add(changeItem);
+ mAms.mUidObserverController.dispatchUidsChanged();
// Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
// the current process state change is also below cutpoint, so no callback will be invoked.
verifyNoMoreInteractions(observer);
changeItem.processState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
- mAms.mPendingUidChanges.add(changeItem);
- mAms.dispatchUidsChanged();
+ mAms.mUidObserverController.mPendingUidChanges.add(changeItem);
+ mAms.mUidObserverController.dispatchUidsChanged();
// Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
// the current process state change is above cutpoint, so callback will be invoked with the
// current process state change.
@@ -675,15 +674,15 @@ public class ActivityManagerServiceTest {
verifyNoMoreInteractions(observer);
changeItem.processState = ActivityManager.PROCESS_STATE_TOP;
- mAms.mPendingUidChanges.add(changeItem);
- mAms.dispatchUidsChanged();
+ mAms.mUidObserverController.mPendingUidChanges.add(changeItem);
+ mAms.mUidObserverController.dispatchUidsChanged();
// Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
// the current process state change is also above cutpoint, so no callback will be invoked.
verifyNoMoreInteractions(observer);
changeItem.processState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
- mAms.mPendingUidChanges.add(changeItem);
- mAms.dispatchUidsChanged();
+ mAms.mUidObserverController.mPendingUidChanges.add(changeItem);
+ mAms.mUidObserverController.dispatchUidsChanged();
// Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
// the current process state change is below cutpoint, so callback will be invoked with the
// current process state change.
@@ -720,20 +719,21 @@ public class ActivityManagerServiceTest {
// Verify that when there no observers listening to uid state changes, then there will
// be no changes to validateUids.
- mAms.mPendingUidChanges.addAll(pendingItemsForUids);
- mAms.dispatchUidsChanged();
+ mAms.mUidObserverController.mPendingUidChanges.addAll(pendingItemsForUids);
+ mAms.mUidObserverController.dispatchUidsChanged();
assertEquals("No observers registered, so validateUids should be empty",
- 0, mAms.mValidateUids.size());
+ 0, mAms.mUidObserverController.mValidateUids.size());
final IUidObserver observer = mock(IUidObserver.Stub.class);
when(observer.asBinder()).thenReturn((IBinder) observer);
mAms.registerUidObserver(observer, 0, 0, null);
// Verify that when observers are registered, then validateUids is correctly updated.
- mAms.mPendingUidChanges.addAll(pendingItemsForUids);
- mAms.dispatchUidsChanged();
+ mAms.mUidObserverController.mPendingUidChanges.addAll(pendingItemsForUids);
+ mAms.mUidObserverController.dispatchUidsChanged();
for (int i = 0; i < pendingItemsForUids.size(); ++i) {
final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
- final UidRecord validateUidRecord = mAms.mValidateUids.get(item.uid);
+ final UidRecord validateUidRecord =
+ mAms.mUidObserverController.mValidateUids.get(item.uid);
if ((item.change & UidRecord.CHANGE_GONE) != 0) {
assertNull("validateUidRecord should be null since the change is either "
+ "CHANGE_GONE or CHANGE_GONE_IDLE", validateUidRecord);
@@ -759,7 +759,7 @@ public class ActivityManagerServiceTest {
// Verify that when uid state changes to CHANGE_GONE or CHANGE_GONE_IDLE, then it
// will be removed from validateUids.
assertNotEquals("validateUids should not be empty", 0,
- mAms.mValidateUids.size());
+ mAms.mUidObserverController.mValidateUids.size());
for (int i = 0; i < pendingItemsForUids.size(); ++i) {
final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
// Assign CHANGE_GONE_IDLE to some items and CHANGE_GONE to the others, using even/odd
@@ -767,10 +767,11 @@ public class ActivityManagerServiceTest {
item.change = (i % 2) == 0 ? (UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE)
: UidRecord.CHANGE_GONE;
}
- mAms.mPendingUidChanges.addAll(pendingItemsForUids);
- mAms.dispatchUidsChanged();
- assertEquals("validateUids should be empty, size=" + mAms.mValidateUids.size(),
- 0, mAms.mValidateUids.size());
+ mAms.mUidObserverController.mPendingUidChanges.addAll(pendingItemsForUids);
+ mAms.mUidObserverController.dispatchUidsChanged();
+ assertEquals("validateUids should be empty, size="
+ + mAms.mUidObserverController.mValidateUids.size(),
+ 0, mAms.mUidObserverController.mValidateUids.size());
}
@Test
@@ -792,7 +793,7 @@ public class ActivityManagerServiceTest {
@Test
public void testEnqueueUidChangeLocked_nullUidRecord() {
// Use "null" uidRecord to make sure there is no crash.
- mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE);
+ mAms.mUidObserverController.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE);
}
private void verifyLastProcStateSeqUpdated(UidRecord uidRecord, int uid, long curProcstateSeq) {
@@ -801,7 +802,7 @@ public class ActivityManagerServiceTest {
final int changeToDispatch = UID_RECORD_CHANGES[i];
// Reset lastProcStateSeqDispatchToObservers after every test.
uidRecord.lastDispatchedProcStateSeq = 0;
- mAms.enqueueUidChangeLocked(uidRecord, uid, changeToDispatch);
+ mAms.mUidObserverController.enqueueUidChangeLocked(uidRecord, uid, changeToDispatch);
// Verify there is no effect on curProcStateSeq.
assertEquals(curProcstateSeq, uidRecord.curProcStateSeq);
if ((changeToDispatch & UidRecord.CHANGE_GONE) != 0) {
@@ -833,9 +834,9 @@ public class ActivityManagerServiceTest {
// Reset the current state
mHandler.reset();
uidRecord.pendingChange = null;
- mAms.mPendingUidChanges.clear();
+ mAms.mUidObserverController.mPendingUidChanges.clear();
- mAms.enqueueUidChangeLocked(uidRecord, -1, changeToDispatch);
+ mAms.mUidObserverController.enqueueUidChangeLocked(uidRecord, -1, changeToDispatch);
// Verify that UidRecord.pendingChange is updated correctly.
assertNotNull(uidRecord.pendingChange);
@@ -843,8 +844,7 @@ public class ActivityManagerServiceTest {
assertEquals(expectedProcState, uidRecord.pendingChange.processState);
assertEquals(TEST_PROC_STATE_SEQ1, uidRecord.pendingChange.procStateSeq);
- // Verify that DISPATCH_UIDS_CHANGED_UI_MSG is posted to handler.
- mHandler.waitForMessage(DISPATCH_UIDS_CHANGED_UI_MSG);
+ // TODO: Verify that DISPATCH_UIDS_CHANGED_UI_MSG is posted to handler.
}
}
diff --git a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
index a9cef20268f4..609af8d5bf4d 100644
--- a/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
+++ b/services/tests/servicestests/src/com/android/server/audio/NoOpAudioSystemAdapter.java
@@ -21,6 +21,8 @@ import android.media.AudioDeviceAttributes;
import android.media.AudioSystem;
import android.util.Log;
+import java.util.List;
+
/**
* Provides an adapter for AudioSystem that does nothing.
* Overridden methods can be configured.
@@ -66,13 +68,13 @@ public class NoOpAudioSystemAdapter extends AudioSystemAdapter {
}
@Override
- public int setPreferredDeviceForStrategy(int strategy,
- @NonNull AudioDeviceAttributes device) {
+ public int setDevicesRoleForStrategy(int strategy, int role,
+ @NonNull List<AudioDeviceAttributes> devices) {
return AudioSystem.AUDIO_STATUS_OK;
}
@Override
- public int removePreferredDeviceForStrategy(int strategy) {
+ public int removeDevicesRoleForStrategy(int strategy, int role) {
return AudioSystem.AUDIO_STATUS_OK;
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
index dad360d40515..36c55cce076b 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
@@ -17,7 +17,6 @@
package com.android.server.biometrics.sensors;
import android.content.Context;
-import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import androidx.annotation.NonNull;
@@ -56,8 +55,8 @@ public class BiometricSchedulerTest {
mScheduler.scheduleClientMonitor(client1);
mScheduler.scheduleClientMonitor(client2);
- client1.mFinishCallback.onClientFinished(client1, true /* success */);
- client1.mFinishCallback.onClientFinished(client1, true /* success */);
+ client1.mCallback.onClientFinished(client1, true /* success */);
+ client1.mCallback.onClientFinished(client1, true /* success */);
}
private static class TestClientMonitor extends ClientMonitor<Object> {
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
index e4c9cc3c05d9..1d914ec083fa 100644
--- a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodUtilsTest.java
@@ -88,36 +88,36 @@ public class InputMethodUtilsTest {
public void testVoiceImes() throws Exception {
// locale: en_US
assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_US,
- "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
+ "FakeDefaultEnKeyboardIme", "FakeDefaultAutoVoiceIme");
assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_US,
- "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
- "DummyNonDefaultAutoVoiceIme1");
+ "FakeDefaultEnKeyboardIme", "FakeNonDefaultAutoVoiceIme0",
+ "FakeNonDefaultAutoVoiceIme1");
assertDefaultEnabledMinimumImes(getImesWithDefaultVoiceIme(), LOCALE_EN_US,
- "DummyDefaultEnKeyboardIme");
+ "FakeDefaultEnKeyboardIme");
assertDefaultEnabledMinimumImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_US,
- "DummyDefaultEnKeyboardIme");
+ "FakeDefaultEnKeyboardIme");
// locale: en_GB
assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_EN_GB,
- "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
+ "FakeDefaultEnKeyboardIme", "FakeDefaultAutoVoiceIme");
assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_GB,
- "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
- "DummyNonDefaultAutoVoiceIme1");
+ "FakeDefaultEnKeyboardIme", "FakeNonDefaultAutoVoiceIme0",
+ "FakeNonDefaultAutoVoiceIme1");
assertDefaultEnabledMinimumImes(getImesWithDefaultVoiceIme(), LOCALE_EN_GB,
- "DummyDefaultEnKeyboardIme");
+ "FakeDefaultEnKeyboardIme");
assertDefaultEnabledMinimumImes(getImesWithoutDefaultVoiceIme(), LOCALE_EN_GB,
- "DummyDefaultEnKeyboardIme");
+ "FakeDefaultEnKeyboardIme");
// locale: ja_JP
assertDefaultEnabledImes(getImesWithDefaultVoiceIme(), LOCALE_JA_JP,
- "DummyDefaultEnKeyboardIme", "DummyDefaultAutoVoiceIme");
+ "FakeDefaultEnKeyboardIme", "FakeDefaultAutoVoiceIme");
assertDefaultEnabledImes(getImesWithoutDefaultVoiceIme(), LOCALE_JA_JP,
- "DummyDefaultEnKeyboardIme", "DummyNonDefaultAutoVoiceIme0",
- "DummyNonDefaultAutoVoiceIme1");
+ "FakeDefaultEnKeyboardIme", "FakeNonDefaultAutoVoiceIme0",
+ "FakeNonDefaultAutoVoiceIme1");
assertDefaultEnabledMinimumImes(getImesWithDefaultVoiceIme(), LOCALE_JA_JP,
- "DummyDefaultEnKeyboardIme");
+ "FakeDefaultEnKeyboardIme");
assertDefaultEnabledMinimumImes(getImesWithoutDefaultVoiceIme(), LOCALE_JA_JP,
- "DummyDefaultEnKeyboardIme");
+ "FakeDefaultEnKeyboardIme");
}
@Test
@@ -189,67 +189,67 @@ public class InputMethodUtilsTest {
@Test
public void testGetImplicitlyApplicableSubtypesLocked() throws Exception {
- final InputMethodSubtype nonAutoEnUS = createDummyInputMethodSubtype("en_US",
+ final InputMethodSubtype nonAutoEnUS = createFakeInputMethodSubtype("en_US",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoEnGB = createDummyInputMethodSubtype("en_GB",
+ final InputMethodSubtype nonAutoEnGB = createFakeInputMethodSubtype("en_GB",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoEnIN = createDummyInputMethodSubtype("en_IN",
+ final InputMethodSubtype nonAutoEnIN = createFakeInputMethodSubtype("en_IN",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoFrCA = createDummyInputMethodSubtype("fr_CA",
+ final InputMethodSubtype nonAutoFrCA = createFakeInputMethodSubtype("fr_CA",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoFr = createDummyInputMethodSubtype("fr_CA",
+ final InputMethodSubtype nonAutoFr = createFakeInputMethodSubtype("fr_CA",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoFil = createDummyInputMethodSubtype("fil",
+ final InputMethodSubtype nonAutoFil = createFakeInputMethodSubtype("fil",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoIn = createDummyInputMethodSubtype("in",
+ final InputMethodSubtype nonAutoIn = createFakeInputMethodSubtype("in",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoId = createDummyInputMethodSubtype("id",
+ final InputMethodSubtype nonAutoId = createFakeInputMethodSubtype("id",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype autoSubtype = createDummyInputMethodSubtype("auto",
+ final InputMethodSubtype autoSubtype = createFakeInputMethodSubtype("auto",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoJa = createDummyInputMethodSubtype("ja",
+ final InputMethodSubtype nonAutoJa = createFakeInputMethodSubtype("ja",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
!IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoHi = createDummyInputMethodSubtype("hi",
+ final InputMethodSubtype nonAutoHi = createFakeInputMethodSubtype("hi",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
!IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoSrCyrl = createDummyInputMethodSubtype("sr",
+ final InputMethodSubtype nonAutoSrCyrl = createFakeInputMethodSubtype("sr",
"sr-Cyrl", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoSrLatn = createDummyInputMethodSubtype("sr_ZZ",
+ final InputMethodSubtype nonAutoSrLatn = createFakeInputMethodSubtype("sr_ZZ",
"sr-Latn", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoHandwritingEn = createDummyInputMethodSubtype("en",
+ final InputMethodSubtype nonAutoHandwritingEn = createFakeInputMethodSubtype("en",
SUBTYPE_MODE_HANDWRITING, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
!IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoHandwritingFr = createDummyInputMethodSubtype("fr",
+ final InputMethodSubtype nonAutoHandwritingFr = createFakeInputMethodSubtype("fr",
SUBTYPE_MODE_HANDWRITING, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
!IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoHandwritingSrCyrl = createDummyInputMethodSubtype("sr",
+ final InputMethodSubtype nonAutoHandwritingSrCyrl = createFakeInputMethodSubtype("sr",
"sr-Cyrl", SUBTYPE_MODE_HANDWRITING, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoHandwritingSrLatn = createDummyInputMethodSubtype("sr_ZZ",
+ final InputMethodSubtype nonAutoHandwritingSrLatn = createFakeInputMethodSubtype("sr_ZZ",
"sr-Latn", SUBTYPE_MODE_HANDWRITING, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
final InputMethodSubtype nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype =
- createDummyInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ createFakeInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
final InputMethodSubtype nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2 =
- createDummyInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ createFakeInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
@@ -266,9 +266,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
subtypes.add(nonAutoHandwritingEn);
subtypes.add(nonAutoHandwritingFr);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -290,9 +290,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
subtypes.add(nonAutoHandwritingEn);
subtypes.add(nonAutoHandwritingFr);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -314,9 +314,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
subtypes.add(nonAutoHandwritingEn);
subtypes.add(nonAutoHandwritingFr);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -339,9 +339,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
subtypes.add(nonAutoHandwritingEn);
subtypes.add(nonAutoHandwritingFr);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -360,9 +360,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
subtypes.add(nonAutoHandwritingEn);
subtypes.add(nonAutoHandwritingFr);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -382,9 +382,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
subtypes.add(nonAutoHandwritingEn);
subtypes.add(nonAutoHandwritingFr);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -404,9 +404,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoHandwritingEn);
subtypes.add(nonAutoHandwritingFr);
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -421,9 +421,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoHandwritingEn);
subtypes.add(nonAutoHandwritingFr);
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -438,9 +438,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoEnUS);
subtypes.add(nonAutoHi);
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -460,9 +460,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoHandwritingFr);
subtypes.add(nonAutoHandwritingSrCyrl);
subtypes.add(nonAutoHandwritingSrLatn);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -480,9 +480,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoHandwritingFr);
subtypes.add(nonAutoHandwritingSrCyrl);
subtypes.add(nonAutoHandwritingSrLatn);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -506,9 +506,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoHandwritingFr);
subtypes.add(nonAutoHandwritingSrCyrl);
subtypes.add(nonAutoHandwritingSrLatn);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -533,9 +533,9 @@ public class InputMethodUtilsTest {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoEnUS);
subtypes.add(nonAutoFil);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -551,9 +551,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoJa);
subtypes.add(nonAutoEnUS);
subtypes.add(nonAutoFil);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -567,9 +567,9 @@ public class InputMethodUtilsTest {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoIn);
subtypes.add(nonAutoEnUS);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -581,9 +581,9 @@ public class InputMethodUtilsTest {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoIn);
subtypes.add(nonAutoEnUS);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -595,9 +595,9 @@ public class InputMethodUtilsTest {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoId);
subtypes.add(nonAutoEnUS);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -609,9 +609,9 @@ public class InputMethodUtilsTest {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoId);
subtypes.add(nonAutoEnUS);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -631,9 +631,9 @@ public class InputMethodUtilsTest {
subtypes.add(nonAutoFil);
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
final ArrayList<InputMethodSubtype> result =
InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
@@ -649,22 +649,22 @@ public class InputMethodUtilsTest {
@Test
public void testContainsSubtypeOf() throws Exception {
- final InputMethodSubtype nonAutoEnUS = createDummyInputMethodSubtype("en_US",
+ final InputMethodSubtype nonAutoEnUS = createFakeInputMethodSubtype("en_US",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoEnGB = createDummyInputMethodSubtype("en_GB",
+ final InputMethodSubtype nonAutoEnGB = createFakeInputMethodSubtype("en_GB",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoFil = createDummyInputMethodSubtype("fil",
+ final InputMethodSubtype nonAutoFil = createFakeInputMethodSubtype("fil",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoFilPH = createDummyInputMethodSubtype("fil_PH",
+ final InputMethodSubtype nonAutoFilPH = createFakeInputMethodSubtype("fil_PH",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoIn = createDummyInputMethodSubtype("in",
+ final InputMethodSubtype nonAutoIn = createFakeInputMethodSubtype("in",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
- final InputMethodSubtype nonAutoId = createDummyInputMethodSubtype("id",
+ final InputMethodSubtype nonAutoId = createFakeInputMethodSubtype("id",
SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE,
IS_ASCII_CAPABLE, IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE);
@@ -673,9 +673,9 @@ public class InputMethodUtilsTest {
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoEnUS);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_EN, !CHECK_COUNTRY,
@@ -705,9 +705,9 @@ public class InputMethodUtilsTest {
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoFil);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, !CHECK_COUNTRY,
SUBTYPE_MODE_KEYBOARD));
@@ -732,9 +732,9 @@ public class InputMethodUtilsTest {
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoFilPH);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_FIL, !CHECK_COUNTRY,
SUBTYPE_MODE_KEYBOARD));
@@ -760,9 +760,9 @@ public class InputMethodUtilsTest {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoIn);
subtypes.add(nonAutoEnUS);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, !CHECK_COUNTRY,
SUBTYPE_MODE_KEYBOARD));
@@ -779,9 +779,9 @@ public class InputMethodUtilsTest {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
subtypes.add(nonAutoId);
subtypes.add(nonAutoEnUS);
- final InputMethodInfo imi = createDummyInputMethodInfo(
+ final InputMethodInfo imi = createFakeInputMethodInfo(
"com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, IS_DEFAULT,
subtypes);
assertTrue(InputMethodUtils.containsSubtypeOf(imi, LOCALE_IN, !CHECK_COUNTRY,
SUBTYPE_MODE_KEYBOARD));
@@ -866,7 +866,7 @@ public class InputMethodUtilsTest {
assertEquals(expected.hashCode(), actual.hashCode());
}
- private static InputMethodInfo createDummyInputMethodInfo(String packageName, String name,
+ private static InputMethodInfo createFakeInputMethodInfo(String packageName, String name,
CharSequence label, boolean isAuxIme, boolean isDefault,
List<InputMethodSubtype> subtypes) {
final ResolveInfo ri = new ResolveInfo();
@@ -885,15 +885,15 @@ public class InputMethodUtilsTest {
return new InputMethodInfo(ri, isAuxIme, "", subtypes, 1, isDefault);
}
- private static InputMethodSubtype createDummyInputMethodSubtype(String locale, String mode,
+ private static InputMethodSubtype createFakeInputMethodSubtype(String locale, String mode,
boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype,
boolean isAsciiCapable, boolean isEnabledWhenDefaultIsNotAsciiCapable) {
- return createDummyInputMethodSubtype(locale, null /* languageTag */, mode, isAuxiliary,
+ return createFakeInputMethodSubtype(locale, null /* languageTag */, mode, isAuxiliary,
overridesImplicitlyEnabledSubtype, isAsciiCapable,
isEnabledWhenDefaultIsNotAsciiCapable);
}
- private static InputMethodSubtype createDummyInputMethodSubtype(String locale,
+ private static InputMethodSubtype createFakeInputMethodSubtype(String locale,
String languageTag, String mode, boolean isAuxiliary,
boolean overridesImplicitlyEnabledSubtype, boolean isAsciiCapable,
boolean isEnabledWhenDefaultIsNotAsciiCapable) {
@@ -920,14 +920,14 @@ public class InputMethodUtilsTest {
ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
- subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("DummyDefaultAutoVoiceIme",
- "dummy.voice0", "DummyVoice0", IS_AUX, IS_DEFAULT, subtypes));
+ preinstalledImes.add(createFakeInputMethodInfo("FakeDefaultAutoVoiceIme",
+ "fake.voice0", "FakeVoice0", IS_AUX, IS_DEFAULT, subtypes));
}
preinstalledImes.addAll(getImesWithoutDefaultVoiceIme());
return preinstalledImes;
@@ -937,41 +937,41 @@ public class InputMethodUtilsTest {
ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
- subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme0",
- "dummy.voice1", "DummyVoice1", IS_AUX, !IS_DEFAULT, subtypes));
+ preinstalledImes.add(createFakeInputMethodInfo("FakeNonDefaultAutoVoiceIme0",
+ "fake.voice1", "FakeVoice1", IS_AUX, !IS_DEFAULT, subtypes));
}
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
- subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme1",
- "dummy.voice2", "DummyVoice2", IS_AUX, !IS_DEFAULT, subtypes));
+ preinstalledImes.add(createFakeInputMethodInfo("FakeNonDefaultAutoVoiceIme1",
+ "fake.voice2", "FakeVoice2", IS_AUX, !IS_DEFAULT, subtypes));
}
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
- subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("DummyNonDefaultVoiceIme2",
- "dummy.voice3", "DummyVoice3", IS_AUX, !IS_DEFAULT, subtypes));
+ preinstalledImes.add(createFakeInputMethodInfo("FakeNonDefaultVoiceIme2",
+ "fake.voice3", "FakeVoice3", IS_AUX, !IS_DEFAULT, subtypes));
}
{
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
- subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("DummyDefaultEnKeyboardIme",
- "dummy.keyboard0", "DummyKeyboard0", !IS_AUX, IS_DEFAULT, subtypes));
+ preinstalledImes.add(createFakeInputMethodInfo("FakeDefaultEnKeyboardIme",
+ "fake.keyboard0", "FakeKeyboard0", !IS_AUX, IS_DEFAULT, subtypes));
}
return preinstalledImes;
}
@@ -991,91 +991,91 @@ public class InputMethodUtilsTest {
private static ArrayList<InputMethodInfo> getSamplePreinstalledImes(final String localeString) {
ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
- // a dummy Voice IME
+ // a fake Voice IME
{
final boolean isDefaultIme = false;
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
- subtypes.add(createDummyInputMethodSubtype("", SUBTYPE_MODE_VOICE, IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("", SUBTYPE_MODE_VOICE, IS_AUX,
IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.voice",
- "com.android.inputmethod.voice", "DummyVoiceIme", IS_AUX, isDefaultIme,
+ preinstalledImes.add(createFakeInputMethodInfo("com.android.apps.inputmethod.voice",
+ "com.android.inputmethod.voice", "FakeVoiceIme", IS_AUX, isDefaultIme,
subtypes));
}
- // a dummy Hindi IME
+ // a fake Hindi IME
{
final boolean isDefaultIme = contains(new String[]{ "hi", "en-rIN" }, localeString);
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
// TODO: This subtype should be marked as IS_ASCII_CAPABLE
- subtypes.add(createDummyInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- subtypes.add(createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.hindi",
- "com.android.inputmethod.hindi", "DummyHindiIme", !IS_AUX, isDefaultIme,
+ preinstalledImes.add(createFakeInputMethodInfo("com.android.apps.inputmethod.hindi",
+ "com.android.inputmethod.hindi", "FakeHindiIme", !IS_AUX, isDefaultIme,
subtypes));
}
- // a dummy Pinyin IME
+ // a fake Pinyin IME
{
final boolean isDefaultIme = contains(new String[]{ "zh-rCN" }, localeString);
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
- subtypes.add(createDummyInputMethodSubtype("zh_CN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("zh_CN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.pinyin",
- "com.android.apps.inputmethod.pinyin", "DummyPinyinIme", !IS_AUX, isDefaultIme,
+ preinstalledImes.add(createFakeInputMethodInfo("com.android.apps.inputmethod.pinyin",
+ "com.android.apps.inputmethod.pinyin", "FakePinyinIme", !IS_AUX, isDefaultIme,
subtypes));
}
- // a dummy Korean IME
+ // a fake Korean IME
{
final boolean isDefaultIme = contains(new String[]{ "ko" }, localeString);
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
- subtypes.add(createDummyInputMethodSubtype("ko", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("ko", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.korean",
- "com.android.apps.inputmethod.korean", "DummyKoreanIme", !IS_AUX, isDefaultIme,
+ preinstalledImes.add(createFakeInputMethodInfo("com.android.apps.inputmethod.korean",
+ "com.android.apps.inputmethod.korean", "FakeKoreanIme", !IS_AUX, isDefaultIme,
subtypes));
}
- // a dummy Latin IME
+ // a fake Latin IME
{
final boolean isDefaultIme = contains(
new String[]{ "en-rUS", "en-rGB", "en-rIN", "en", "hi" }, localeString);
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
- subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- subtypes.add(createDummyInputMethodSubtype("en_GB", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("en_GB", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- subtypes.add(createDummyInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- subtypes.add(createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.latin",
- "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, isDefaultIme,
+ preinstalledImes.add(createFakeInputMethodInfo("com.android.apps.inputmethod.latin",
+ "com.android.apps.inputmethod.latin", "FakeLatinIme", !IS_AUX, isDefaultIme,
subtypes));
}
- // a dummy Japanese IME
+ // a fake Japanese IME
{
final boolean isDefaultIme = contains(new String[]{ "ja", "ja-rJP" }, localeString);
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
- subtypes.add(createDummyInputMethodSubtype("ja", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("ja", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- subtypes.add(createDummyInputMethodSubtype("emoji", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
+ subtypes.add(createFakeInputMethodSubtype("emoji", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
!IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
!IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
- preinstalledImes.add(createDummyInputMethodInfo("com.android.apps.inputmethod.japanese",
- "com.android.apps.inputmethod.japanese", "DummyJapaneseIme", !IS_AUX,
+ preinstalledImes.add(createFakeInputMethodInfo("com.android.apps.inputmethod.japanese",
+ "com.android.apps.inputmethod.japanese", "FakeJapaneseIme", !IS_AUX,
isDefaultIme, subtypes));
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index 1b5c56a4b4c9..d44d37e4e2a1 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -19,7 +19,6 @@ package com.android.server.locksettings;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
@@ -169,7 +168,7 @@ public abstract class BaseLockSettingsServiceTests {
final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
allUsers.add(SECONDARY_USER_INFO);
- when(mUserManager.getUsers(anyBoolean())).thenReturn(allUsers);
+ when(mUserManager.getUsers()).thenReturn(allUsers);
when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
new Answer<Boolean>() {
diff --git a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
index 083df28b2278..aaa74dd832af 100644
--- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
@@ -284,28 +284,29 @@ public class ThermalManagerServiceTest {
@Test
public void testNotify() throws RemoteException {
int status = Temperature.THROTTLING_SEVERE;
+ // Should only notify event not status
Temperature newBattery = new Temperature(50, Temperature.TYPE_BATTERY, "batt", status);
mFakeHal.mCallback.onValues(newBattery);
verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).notifyThrottling(newBattery);
verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(1)).onStatusChange(status);
+ .times(0)).onStatusChange(anyInt());
verify(mEventListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(0)).notifyThrottling(newBattery);
verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(1)).onStatusChange(status);
+ .times(0)).onStatusChange(anyInt());
resetListenerMock();
- // Should only notify event not status
+ // Notify both event and status
Temperature newSkin = new Temperature(50, Temperature.TYPE_SKIN, "skin1", status);
mFakeHal.mCallback.onValues(newSkin);
verify(mEventListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).notifyThrottling(newSkin);
verify(mStatusListener1, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(0)).onStatusChange(anyInt());
+ .times(1)).onStatusChange(status);
verify(mEventListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
.times(1)).notifyThrottling(newSkin);
verify(mStatusListener2, timeout(CALLBACK_TIMEOUT_MILLI_SEC)
- .times(0)).onStatusChange(anyInt());
+ .times(1)).onStatusChange(status);
resetListenerMock();
// Back to None, should only notify event not status
status = Temperature.THROTTLING_NONE;
@@ -345,10 +346,13 @@ public class ThermalManagerServiceTest {
@Test
public void testGetCurrentStatus() throws RemoteException {
- int status = Temperature.THROTTLING_EMERGENCY;
+ int status = Temperature.THROTTLING_SEVERE;
Temperature newSkin = new Temperature(100, Temperature.TYPE_SKIN, "skin1", status);
mFakeHal.mCallback.onValues(newSkin);
assertEquals(status, mService.mService.getCurrentThermalStatus());
+ int battStatus = Temperature.THROTTLING_EMERGENCY;
+ Temperature newBattery = new Temperature(60, Temperature.TYPE_BATTERY, "batt", battStatus);
+ assertEquals(status, mService.mService.getCurrentThermalStatus());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
index f9343236662b..7b07102356f0 100644
--- a/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/tv/tunerresourcemanager/TunerResourceManagerServiceTest.java
@@ -74,7 +74,7 @@ public class TunerResourceManagerServiceTest {
mReclaimed = true;
}
- public boolean isRelaimed() {
+ public boolean isReclaimed() {
return mReclaimed;
}
}
@@ -387,13 +387,13 @@ public class TunerResourceManagerServiceTest {
new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBT);
assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isFalse();
- assertThat(listener.isRelaimed()).isFalse();
+ assertThat(listener.isReclaimed()).isFalse();
request =
new TunerFrontendRequest(clientId1[0] /*clientId*/, FrontendSettings.TYPE_DVBS);
assertThat(mTunerResourceManagerService
.requestFrontendInternal(request, frontendHandle)).isFalse();
- assertThat(listener.isRelaimed()).isFalse();
+ assertThat(listener.isReclaimed()).isFalse();
}
@Test
@@ -452,7 +452,7 @@ public class TunerResourceManagerServiceTest {
.getOwnerClientId()).isEqualTo(clientId1[0]);
assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
.getOwnerClientId()).isEqualTo(clientId1[0]);
- assertThat(listener.isRelaimed()).isTrue();
+ assertThat(listener.isReclaimed()).isTrue();
}
@Test
@@ -486,7 +486,7 @@ public class TunerResourceManagerServiceTest {
// Release frontend
mTunerResourceManagerService.releaseFrontendInternal(mTunerResourceManagerService
- .getFrontendResource(frontendId));
+ .getFrontendResource(frontendId), clientId[0]);
assertThat(mTunerResourceManagerService
.getFrontendResource(frontendId).isInUse()).isFalse();
assertThat(mTunerResourceManagerService
@@ -548,7 +548,7 @@ public class TunerResourceManagerServiceTest {
assertThat(mTunerResourceManagerService.getCasResource(1)
.getOwnerClientIds()).isEqualTo(new HashSet<Integer>(Arrays.asList(clientId1[0])));
assertThat(mTunerResourceManagerService.getCasResource(1).isFullyUsed()).isFalse();
- assertThat(listener.isRelaimed()).isTrue();
+ assertThat(listener.isReclaimed()).isTrue();
}
@Test
@@ -633,7 +633,7 @@ public class TunerResourceManagerServiceTest {
.isInUse()).isTrue();
assertThat(mTunerResourceManagerService.getLnbResource(lnbIds[0])
.getOwnerClientId()).isEqualTo(clientId1[0]);
- assertThat(listener.isRelaimed()).isTrue();
+ assertThat(listener.isReclaimed()).isTrue();
assertThat(mTunerResourceManagerService.getClientProfile(clientId0[0])
.getInUseLnbIds().size()).isEqualTo(0);
}
@@ -761,4 +761,293 @@ public class TunerResourceManagerServiceTest {
backgroundRecordProfile)).isEqualTo(
(backgroundPlaybackPriority > backgroundRecordPriority));
}
+
+ @Test
+ public void shareFrontendTest_FrontendWithExclusiveGroupReadyToShare() {
+ /**** Register Clients and Set Priority ****/
+
+ // Int array to save the returned client ids
+ int[] ownerClientId0 = new int[1];
+ int[] ownerClientId1 = new int[1];
+ int[] shareClientId0 = new int[1];
+ int[] shareClientId1 = new int[1];
+
+ // Predefined client profiles
+ ResourceClientProfile[] ownerProfiles = new ResourceClientProfile[2];
+ ResourceClientProfile[] shareProfiles = new ResourceClientProfile[2];
+ ownerProfiles[0] = new ResourceClientProfile(
+ "0" /*sessionId*/,
+ TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE);
+ ownerProfiles[1] = new ResourceClientProfile(
+ "1" /*sessionId*/,
+ TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE);
+ shareProfiles[0] = new ResourceClientProfile(
+ "2" /*sessionId*/,
+ TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD);
+ shareProfiles[1] = new ResourceClientProfile(
+ "3" /*sessionId*/,
+ TvInputService.PRIORITY_HINT_USE_CASE_TYPE_RECORD);
+
+ // Predefined client reclaim listeners
+ TestResourcesReclaimListener ownerListener0 = new TestResourcesReclaimListener();
+ TestResourcesReclaimListener shareListener0 = new TestResourcesReclaimListener();
+ TestResourcesReclaimListener ownerListener1 = new TestResourcesReclaimListener();
+ TestResourcesReclaimListener shareListener1 = new TestResourcesReclaimListener();
+ // Register clients and validate the returned client ids
+ mTunerResourceManagerService
+ .registerClientProfileInternal(ownerProfiles[0], ownerListener0, ownerClientId0);
+ mTunerResourceManagerService
+ .registerClientProfileInternal(shareProfiles[0], shareListener0, shareClientId0);
+ mTunerResourceManagerService
+ .registerClientProfileInternal(ownerProfiles[1], ownerListener1, ownerClientId1);
+ mTunerResourceManagerService
+ .registerClientProfileInternal(shareProfiles[1], shareListener1, shareClientId1);
+ assertThat(ownerClientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
+ assertThat(shareClientId0[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
+ assertThat(ownerClientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
+ assertThat(shareClientId1[0]).isNotEqualTo(TunerResourceManagerService.INVALID_CLIENT_ID);
+
+ mTunerResourceManagerService.updateClientPriorityInternal(
+ ownerClientId0[0],
+ 100/*priority*/,
+ 0/*niceValue*/);
+ mTunerResourceManagerService.updateClientPriorityInternal(
+ shareClientId0[0],
+ 200/*priority*/,
+ 0/*niceValue*/);
+ mTunerResourceManagerService.updateClientPriorityInternal(
+ ownerClientId1[0],
+ 300/*priority*/,
+ 0/*niceValue*/);
+ mTunerResourceManagerService.updateClientPriorityInternal(
+ shareClientId1[0],
+ 400/*priority*/,
+ 0/*niceValue*/);
+
+ /**** Init Frontend Resources ****/
+
+ // Predefined frontend info
+ TunerFrontendInfo[] infos = new TunerFrontendInfo[2];
+ infos[0] = new TunerFrontendInfo(
+ 0 /*id*/,
+ FrontendSettings.TYPE_DVBT,
+ 1 /*exclusiveGroupId*/);
+ infos[1] = new TunerFrontendInfo(
+ 1 /*id*/,
+ FrontendSettings.TYPE_DVBS,
+ 1 /*exclusiveGroupId*/);
+
+ /**** Init Lnb Resources ****/
+ int[] lnbIds = {1};
+ mTunerResourceManagerService.setLnbInfoListInternal(lnbIds);
+
+ // Update frontend list in TRM
+ mTunerResourceManagerService.setFrontendInfoListInternal(infos);
+
+ /**** Request Frontend ****/
+
+ // Predefined frontend request and array to save returned frontend handle
+ int[] frontendHandle = new int[1];
+ TunerFrontendRequest request = new TunerFrontendRequest(
+ ownerClientId0[0] /*clientId*/,
+ FrontendSettings.TYPE_DVBT);
+
+ // Request call and validate granted resource and internal mapping
+ assertThat(mTunerResourceManagerService
+ .requestFrontendInternal(request, frontendHandle))
+ .isTrue();
+ assertThat(mTunerResourceManagerService
+ .getResourceIdFromHandle(frontendHandle[0]))
+ .isEqualTo(infos[0].getId());
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(ownerClientId0[0])
+ .getInUseFrontendIds())
+ .isEqualTo(new HashSet<Integer>(Arrays.asList(
+ infos[0].getId(),
+ infos[1].getId())));
+
+ /**** Share Frontend ****/
+
+ // Share frontend call and validate the internal mapping
+ mTunerResourceManagerService.shareFrontendInternal(
+ shareClientId0[0]/*selfClientId*/,
+ ownerClientId0[0]/*targetClientId*/);
+ mTunerResourceManagerService.shareFrontendInternal(
+ shareClientId1[0]/*selfClientId*/,
+ ownerClientId0[0]/*targetClientId*/);
+ // Verify fe in use status
+ assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
+ .isInUse()).isTrue();
+ assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
+ .isInUse()).isTrue();
+ // Verify fe owner status
+ assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
+ .getOwnerClientId()).isEqualTo(ownerClientId0[0]);
+ assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
+ .getOwnerClientId()).isEqualTo(ownerClientId0[0]);
+ // Verify share fe client status in the primary owner client
+ assertThat(mTunerResourceManagerService.getClientProfile(ownerClientId0[0])
+ .getShareFeClientIds())
+ .isEqualTo(new HashSet<Integer>(Arrays.asList(
+ shareClientId0[0],
+ shareClientId1[0])));
+ // Verify in use frontend list in all the primary owner and share owner clients
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(ownerClientId0[0])
+ .getInUseFrontendIds())
+ .isEqualTo(new HashSet<Integer>(Arrays.asList(
+ infos[0].getId(),
+ infos[1].getId())));
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(shareClientId0[0])
+ .getInUseFrontendIds())
+ .isEqualTo(new HashSet<Integer>(Arrays.asList(
+ infos[0].getId(),
+ infos[1].getId())));
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(shareClientId1[0])
+ .getInUseFrontendIds())
+ .isEqualTo(new HashSet<Integer>(Arrays.asList(
+ infos[0].getId(),
+ infos[1].getId())));
+
+ /**** Remove Frontend Share Owner ****/
+
+ // Unregister the second share fe client
+ mTunerResourceManagerService.unregisterClientProfileInternal(shareClientId1[0]);
+
+ // Validate the internal mapping
+ assertThat(mTunerResourceManagerService.getClientProfile(ownerClientId0[0])
+ .getShareFeClientIds())
+ .isEqualTo(new HashSet<Integer>(Arrays.asList(
+ shareClientId0[0])));
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(ownerClientId0[0])
+ .getInUseFrontendIds())
+ .isEqualTo(new HashSet<Integer>(Arrays.asList(
+ infos[0].getId(),
+ infos[1].getId())));
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(shareClientId0[0])
+ .getInUseFrontendIds())
+ .isEqualTo(new HashSet<Integer>(Arrays.asList(
+ infos[0].getId(),
+ infos[1].getId())));
+
+ /**** Request Shared Frontend with Higher Priority Client ****/
+
+ // Predefined second frontend request
+ request = new TunerFrontendRequest(
+ ownerClientId1[0] /*clientId*/,
+ FrontendSettings.TYPE_DVBT);
+
+ // Second request call
+ assertThat(mTunerResourceManagerService
+ .requestFrontendInternal(request, frontendHandle))
+ .isTrue();
+
+ // Validate granted resource and internal mapping
+ assertThat(mTunerResourceManagerService
+ .getResourceIdFromHandle(frontendHandle[0]))
+ .isEqualTo(infos[0].getId());
+ assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
+ .getOwnerClientId()).isEqualTo(ownerClientId1[0]);
+ assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
+ .getOwnerClientId()).isEqualTo(ownerClientId1[0]);
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(ownerClientId1[0])
+ .getInUseFrontendIds())
+ .isEqualTo(new HashSet<Integer>(Arrays.asList(
+ infos[0].getId(),
+ infos[1].getId())));
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(ownerClientId0[0])
+ .getInUseFrontendIds()
+ .isEmpty())
+ .isTrue();
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(shareClientId0[0])
+ .getInUseFrontendIds()
+ .isEmpty())
+ .isTrue();
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(ownerClientId0[0])
+ .getShareFeClientIds()
+ .isEmpty())
+ .isTrue();
+ assertThat(ownerListener0.isReclaimed()).isTrue();
+ assertThat(shareListener0.isReclaimed()).isTrue();
+
+ /**** Release Frontend Resource From Primary Owner ****/
+
+ // Reshare the frontend
+ mTunerResourceManagerService.shareFrontendInternal(
+ shareClientId0[0]/*selfClientId*/,
+ ownerClientId1[0]/*targetClientId*/);
+
+ // Release the frontend resource from the primary owner
+ mTunerResourceManagerService.releaseFrontendInternal(mTunerResourceManagerService
+ .getFrontendResource(infos[0].getId()), ownerClientId1[0]);
+
+ // Validate the internal mapping
+ assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
+ .isInUse()).isFalse();
+ assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
+ .isInUse()).isFalse();
+ // Verify client status
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(ownerClientId1[0])
+ .getInUseFrontendIds()
+ .isEmpty())
+ .isTrue();
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(shareClientId0[0])
+ .getInUseFrontendIds()
+ .isEmpty())
+ .isTrue();
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(ownerClientId1[0])
+ .getShareFeClientIds()
+ .isEmpty())
+ .isTrue();
+
+ /**** Unregister Primary Owner when the Share owner owns an Lnb ****/
+
+ // Predefined Lnb request and handle array
+ TunerLnbRequest requestLnb = new TunerLnbRequest(shareClientId0[0]);
+ int[] lnbHandle = new int[1];
+
+ // Request for an Lnb
+ assertThat(mTunerResourceManagerService
+ .requestLnbInternal(requestLnb, lnbHandle))
+ .isTrue();
+
+ // Request and share the frontend resource again
+ assertThat(mTunerResourceManagerService
+ .requestFrontendInternal(request, frontendHandle))
+ .isTrue();
+ mTunerResourceManagerService.shareFrontendInternal(
+ shareClientId0[0]/*selfClientId*/,
+ ownerClientId1[0]/*targetClientId*/);
+
+ // Unregister the primary owner of the shared frontend
+ mTunerResourceManagerService.unregisterClientProfileInternal(ownerClientId1[0]);
+
+ // Validate the internal mapping
+ assertThat(mTunerResourceManagerService.getFrontendResource(infos[0].getId())
+ .isInUse()).isFalse();
+ assertThat(mTunerResourceManagerService.getFrontendResource(infos[1].getId())
+ .isInUse()).isFalse();
+ // Verify client status
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(shareClientId0[0])
+ .getInUseFrontendIds()
+ .isEmpty())
+ .isTrue();
+ assertThat(mTunerResourceManagerService
+ .getClientProfile(shareClientId0[0])
+ .getInUseLnbIds())
+ .isEqualTo(new HashSet<Integer>(Arrays.asList(
+ lnbIds[0])));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 4dec7a1a0ab9..7c7b1a296673 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -1383,7 +1383,7 @@ public class AppStandbyControllerTests {
getStandbyBucket(mController, PACKAGE_1));
mController.postReportSyncScheduled(PACKAGE_1, USER_ID, false);
- mStateChangedLatch.await(100, TimeUnit.MILLISECONDS);
+ mStateChangedLatch.await(1000, TimeUnit.MILLISECONDS);
assertEquals("Unexempted sync scheduled should bring the package out of the Never bucket",
STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController, PACKAGE_1));
@@ -1391,7 +1391,7 @@ public class AppStandbyControllerTests {
mStateChangedLatch = new CountDownLatch(1);
mController.postReportSyncScheduled(PACKAGE_1, USER_ID, false);
- mStateChangedLatch.await(100, TimeUnit.MILLISECONDS);
+ mStateChangedLatch.await(1000, TimeUnit.MILLISECONDS);
assertEquals("Unexempted sync scheduled should not elevate a non Never bucket",
STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
}
@@ -1402,7 +1402,7 @@ public class AppStandbyControllerTests {
mInjector.mDeviceIdleMode = true;
mStateChangedLatch = new CountDownLatch(1);
mController.postReportSyncScheduled(PACKAGE_1, USER_ID, true);
- mStateChangedLatch.await(100, TimeUnit.MILLISECONDS);
+ mStateChangedLatch.await(1000, TimeUnit.MILLISECONDS);
assertEquals("Exempted sync scheduled in doze should set bucket to working set",
STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController, PACKAGE_1));
@@ -1410,7 +1410,7 @@ public class AppStandbyControllerTests {
mInjector.mDeviceIdleMode = false;
mStateChangedLatch = new CountDownLatch(1);
mController.postReportSyncScheduled(PACKAGE_1, USER_ID, true);
- mStateChangedLatch.await(100, TimeUnit.MILLISECONDS);
+ mStateChangedLatch.await(1000, TimeUnit.MILLISECONDS);
assertEquals("Exempted sync scheduled while not in doze should set bucket to active",
STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
}
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 5b2d738eb760..9319bea497fb 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -3886,7 +3886,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.updateUriPermissions(recordB, recordA, mContext.getPackageName(),
USER_SYSTEM);
verify(mUgmInternal, times(1)).revokeUriPermissionFromOwner(any(),
- eq(message1.getDataUri()), anyInt(), anyInt());
+ eq(message1.getDataUri()), anyInt(), anyInt(), eq(null), eq(-1));
// Update back means we grant access to first again
reset(mUgm);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index 96b970056c98..1e95aba0c2d7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -192,6 +192,8 @@ public class ActivityStackSupervisorTests extends WindowTestsBase {
virtualDisplay.getDisplay().getDisplayId(), unresizableActivity.info);
assertThat(allowed).isTrue();
+
+ virtualDisplay.release();
}
@Test
@@ -206,6 +208,8 @@ public class ActivityStackSupervisorTests extends WindowTestsBase {
virtualDisplay.getDisplay().getDisplayId(), unresizableActivity.info);
assertThat(allowed).isFalse();
+
+ virtualDisplay.release();
}
private VirtualDisplay createVirtualDisplay(boolean trusted) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java b/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
index 8223024234fb..578a43cba33d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
@@ -38,13 +38,13 @@ import org.junit.Test;
*/
@SmallTest
@Presubmit
-@Ignore("b/163095037")
public class ProtoLogIntegrationTest {
@After
public void tearDown() {
ProtoLogImpl.setSingleInstance(null);
}
+ @Ignore("b/163095037")
@Test
public void testProtoLogToolIntegration() {
ProtoLogImpl mockedProtoLog = mock(ProtoLogImpl.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 2f736555ae1b..189e540af0ca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.Display.INVALID_DISPLAY;
@@ -253,6 +255,19 @@ public class WindowProcessControllerTests extends WindowTestsBase {
assertFalse(mWpc.registeredForActivityConfigChanges());
}
+ @Test
+ public void testProcessLevelConfiguration() {
+ Configuration config = new Configuration();
+ config.windowConfiguration.setActivityType(ACTIVITY_TYPE_HOME);
+ mWpc.onRequestedOverrideConfigurationChanged(config);
+ assertEquals(ACTIVITY_TYPE_HOME, config.windowConfiguration.getActivityType());
+ assertEquals(ACTIVITY_TYPE_UNDEFINED, mWpc.getActivityType());
+
+ mWpc.onMergedOverrideConfigurationChanged(config);
+ assertEquals(ACTIVITY_TYPE_HOME, config.windowConfiguration.getActivityType());
+ assertEquals(ACTIVITY_TYPE_UNDEFINED, mWpc.getActivityType());
+ }
+
private TestDisplayContent createTestDisplayContentInContainer() {
return new TestDisplayContent.Builder(mAtm, 1000, 1500).build();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index d9c48fc4ba37..e0785c13a336 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -27,6 +27,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -145,29 +146,40 @@ public class WindowTokenTests extends WindowTestsBase {
assertEquals(0, token.getWindowsCount());
}
- @UseTestDisplay(addWindows = { W_ACTIVITY, W_WALLPAPER })
@Test
public void testFinishFixedRotationTransform() {
- final WindowToken appToken = mAppWindow.mToken;
- final WindowToken wallpaperToken = mWallpaperWindow.mToken;
+ final WindowToken[] tokens = new WindowToken[3];
+ for (int i = 0; i < tokens.length; i++) {
+ tokens[i] = createTestWindowToken(TYPE_APPLICATION_OVERLAY, mDisplayContent);
+ }
+
final Configuration config = new Configuration(mDisplayContent.getConfiguration());
final int originalRotation = config.windowConfiguration.getRotation();
final int targetRotation = (originalRotation + 1) % 4;
config.windowConfiguration.setRotation(targetRotation);
- appToken.applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config);
- wallpaperToken.linkFixedRotationTransform(appToken);
+ tokens[0].applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config);
+ tokens[1].linkFixedRotationTransform(tokens[0]);
// The window tokens should apply the rotation by the transformation.
- assertEquals(targetRotation, appToken.getWindowConfiguration().getRotation());
- assertEquals(targetRotation, wallpaperToken.getWindowConfiguration().getRotation());
+ assertEquals(targetRotation, tokens[0].getWindowConfiguration().getRotation());
+ assertEquals(targetRotation, tokens[1].getWindowConfiguration().getRotation());
+
+ tokens[2].applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config);
+ // The tokens[1] was linked to tokens[0], this should make tokens[1] link to tokens[2].
+ tokens[1].linkFixedRotationTransform(tokens[2]);
+
+ // Assume the display doesn't rotate, the transformation will be canceled.
+ tokens[0].finishFixedRotationTransform();
- // The display doesn't rotate, the transformation will be canceled.
- mAppWindow.mToken.finishFixedRotationTransform();
+ // The tokens[0] should restore to the original rotation.
+ assertEquals(originalRotation, tokens[0].getWindowConfiguration().getRotation());
+ // The tokens[1] is linked to tokens[2], it should keep the target rotation.
+ assertNotEquals(originalRotation, tokens[1].getWindowConfiguration().getRotation());
- // The window tokens should restore to the original rotation.
- assertEquals(originalRotation, appToken.getWindowConfiguration().getRotation());
- assertEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation());
+ tokens[2].finishFixedRotationTransform();
+ // The rotation of tokens[1] should be restored because its linked state is finished.
+ assertEquals(originalRotation, tokens[1].getWindowConfiguration().getRotation());
}
/**
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 78556ef41edb..1e5d92b270d2 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -61,7 +61,6 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutServiceInternal;
-import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.os.Binder;
import android.os.Environment;
@@ -306,25 +305,25 @@ public class UsageStatsService extends SystemService implements
@Override
public void onUserStopping(@NonNull TargetUser user) {
- final UserInfo userInfo = user.getUserInfo();
+ final int userId = user.getUserIdentifier();
synchronized (mLock) {
// User was started but never unlocked so no need to report a user stopped event
- if (!mUserUnlockedStates.get(userInfo.id)) {
- persistPendingEventsLocked(userInfo.id);
+ if (!mUserUnlockedStates.get(userId)) {
+ persistPendingEventsLocked(userId);
return;
}
// Report a user stopped event before persisting all stats to disk via the user service
final Event event = new Event(USER_STOPPED, SystemClock.elapsedRealtime());
event.mPackage = Event.DEVICE_EVENT_PACKAGE_NAME;
- reportEvent(event, userInfo.id);
- final UserUsageStatsService userService = mUserState.get(userInfo.id);
+ reportEvent(event, userId);
+ final UserUsageStatsService userService = mUserState.get(userId);
if (userService != null) {
userService.userStopped();
}
- mUserUnlockedStates.put(userInfo.id, false);
- mUserState.put(userInfo.id, null); // release the service (mainly for GC)
+ mUserUnlockedStates.put(userId, false);
+ mUserState.put(userId, null); // release the service (mainly for GC)
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 0f898f8e679e..a2215ceed36a 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -164,13 +164,13 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
- private boolean isSupported(UserInfo user) {
+ @Override
+ public boolean isUserSupported(@NonNull TargetUser user) {
return user.isFull();
}
- @Override
- public boolean isUserSupported(TargetUser user) {
- return isSupported(user.getUserInfo());
+ private boolean isUserSupported(@NonNull UserInfo user) {
+ return user.isFull();
}
@Override
@@ -461,7 +461,7 @@ public class VoiceInteractionManagerService extends SystemService {
private void setCurrentUserLocked(@UserIdInt int userHandle) {
mCurUser = userHandle;
final UserInfo userInfo = mUserManagerInternal.getUserInfo(mCurUser);
- mCurUserSupported = isSupported(userInfo);
+ mCurUserSupported = isUserSupported(userInfo);
}
public void switchUser(@UserIdInt int userHandle) {
@@ -967,10 +967,10 @@ public class VoiceInteractionManagerService extends SystemService {
throw new IllegalArgumentException("Illegal argument(s) in getKeyphraseSoundModel");
}
- final int callingUid = UserHandle.getCallingUserId();
+ final int callingUserId = UserHandle.getCallingUserId();
final long caller = Binder.clearCallingIdentity();
try {
- return mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale);
+ return mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUserId, bcp47Locale);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -1010,7 +1010,7 @@ public class VoiceInteractionManagerService extends SystemService {
"Illegal argument(s) in deleteKeyphraseSoundModel");
}
- final int callingUid = UserHandle.getCallingUserId();
+ final int callingUserId = UserHandle.getCallingUserId();
final long caller = Binder.clearCallingIdentity();
boolean deleted = false;
try {
@@ -1018,7 +1018,8 @@ public class VoiceInteractionManagerService extends SystemService {
if (unloadStatus != SoundTriggerInternal.STATUS_OK) {
Slog.w(TAG, "Unable to unload keyphrase sound model:" + unloadStatus);
}
- deleted = mDbHelper.deleteKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale);
+ deleted = mDbHelper.deleteKeyphraseSoundModel(
+ keyphraseId, callingUserId, bcp47Locale);
return deleted ? SoundTriggerInternal.STATUS_OK : SoundTriggerInternal.STATUS_ERROR;
} finally {
if (deleted) {
@@ -1045,11 +1046,11 @@ public class VoiceInteractionManagerService extends SystemService {
throw new IllegalArgumentException("Illegal argument(s) in isEnrolledForKeyphrase");
}
- final int callingUid = UserHandle.getCallingUserId();
+ final int callingUserId = UserHandle.getCallingUserId();
final long caller = Binder.clearCallingIdentity();
try {
KeyphraseSoundModel model =
- mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale);
+ mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUserId, bcp47Locale);
return model != null;
} finally {
Binder.restoreCallingIdentity(caller);
@@ -1067,11 +1068,11 @@ public class VoiceInteractionManagerService extends SystemService {
throw new IllegalArgumentException("Illegal argument(s) in isEnrolledForKeyphrase");
}
- final int callingUid = UserHandle.getCallingUserId();
+ final int callingUserId = UserHandle.getCallingUserId();
final long caller = Binder.clearCallingIdentity();
try {
KeyphraseSoundModel model =
- mDbHelper.getKeyphraseSoundModel(keyphrase, callingUid, bcp47Locale);
+ mDbHelper.getKeyphraseSoundModel(keyphrase, callingUserId, bcp47Locale);
if (model == null) {
return null;
}
@@ -1118,11 +1119,11 @@ public class VoiceInteractionManagerService extends SystemService {
}
}
- int callingUid = UserHandle.getCallingUserId();
+ final int callingUserId = UserHandle.getCallingUserId();
final long caller = Binder.clearCallingIdentity();
try {
KeyphraseSoundModel soundModel =
- mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale);
+ mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUserId, bcp47Locale);
if (soundModel == null
|| soundModel.getUuid() == null
|| soundModel.getKeyphrases() == null) {
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 3646647e9734..6288bc1698e9 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -2488,6 +2488,42 @@ public abstract class ConnectionService extends Service {
}
/**
+ * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
+ * incoming request. This is used by {@code ConnectionService}s that are registered with
+ * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
+ *
+ * @param connectionManagerPhoneAccount See description at
+ * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
+ * @param request Details about the incoming conference call.
+ * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
+ * handle the call.
+ */
+ public final @Nullable RemoteConference createRemoteIncomingConference(
+ @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
+ @Nullable ConnectionRequest request) {
+ return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
+ request, true);
+ }
+
+ /**
+ * Ask some other {@code ConnectionService} to create a {@code RemoteConference} given an
+ * outgoing request. This is used by {@code ConnectionService}s that are registered with
+ * {@link PhoneAccount#CAPABILITY_ADHOC_CONFERENCE_CALLING}.
+ *
+ * @param connectionManagerPhoneAccount See description at
+ * {@link #onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
+ * @param request Details about the outgoing conference call.
+ * @return The {@code RemoteConference} object to satisfy this call, or {@code null} to not
+ * handle the call.
+ */
+ public final @Nullable RemoteConference createRemoteOutgoingConference(
+ @Nullable PhoneAccountHandle connectionManagerPhoneAccount,
+ @Nullable ConnectionRequest request) {
+ return mRemoteConnectionManager.createRemoteConference(connectionManagerPhoneAccount,
+ request, false);
+ }
+
+ /**
* Indicates to the relevant {@code RemoteConnectionService} that the specified
* {@link RemoteConnection}s should be merged into a conference call.
* <p>
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index 502b7c01b0c0..e024e6186519 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -16,14 +16,14 @@
package android.telecom;
-import com.android.internal.telecom.IConnectionService;
-
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
+import com.android.internal.telecom.IConnectionService;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -155,6 +155,14 @@ public final class RemoteConference {
}
/** @hide */
+ RemoteConference(DisconnectCause disconnectCause) {
+ mId = "NULL";
+ mConnectionService = null;
+ mState = Connection.STATE_DISCONNECTED;
+ mDisconnectCause = disconnectCause;
+ }
+
+ /** @hide */
String getId() {
return mId;
}
@@ -583,4 +591,16 @@ public final class RemoteConference {
}
}
}
+
+ /**
+ * Create a {@link RemoteConference} represents a failure, and which will
+ * be in {@link Connection#STATE_DISCONNECTED}.
+ *
+ * @param disconnectCause The disconnect cause.
+ * @return a failed {@link RemoteConference}
+ * @hide
+ */
+ public static RemoteConference failure(DisconnectCause disconnectCause) {
+ return new RemoteConference(disconnectCause);
+ }
}
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index df3362578680..52210a55c8d0 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -16,10 +16,6 @@
package android.telecom;
-import com.android.internal.telecom.IConnectionService;
-import com.android.internal.telecom.IVideoCallback;
-import com.android.internal.telecom.IVideoProvider;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -33,6 +29,10 @@ import android.os.RemoteException;
import android.telecom.Logging.Session;
import android.view.Surface;
+import com.android.internal.telecom.IConnectionService;
+import com.android.internal.telecom.IVideoCallback;
+import com.android.internal.telecom.IVideoProvider;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -1114,6 +1114,23 @@ public final class RemoteConnection {
}
/**
+ * Instructs this {@link RemoteConnection} to initiate a conference with a list of
+ * participants.
+ * <p>
+ *
+ * @param participants with which conference call will be formed.
+ */
+ public void addConferenceParticipants(@NonNull List<Uri> participants) {
+ try {
+ if (mConnected) {
+ mConnectionService.addConferenceParticipants(mConnectionId, participants,
+ null /*Session.Info*/);
+ }
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ /**
* Set the audio state of this {@code RemoteConnection}.
*
* @param state The audio state of this {@code RemoteConnection}.
diff --git a/telecomm/java/android/telecom/RemoteConnectionManager.java b/telecomm/java/android/telecom/RemoteConnectionManager.java
index 0322218d75dc..f3c7bd83ed4b 100644
--- a/telecomm/java/android/telecom/RemoteConnectionManager.java
+++ b/telecomm/java/android/telecom/RemoteConnectionManager.java
@@ -73,6 +73,37 @@ public class RemoteConnectionManager {
return null;
}
+ /**
+ * Ask a {@code RemoteConnectionService} to create a {@code RemoteConference}.
+ * @param connectionManagerPhoneAccount See description at
+ * {@link ConnectionService#onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)}.
+ * @param request Details about the incoming conference call.
+ * @param isIncoming {@code true} if it's an incoming conference.
+ * @return
+ */
+ public RemoteConference createRemoteConference(
+ PhoneAccountHandle connectionManagerPhoneAccount,
+ ConnectionRequest request,
+ boolean isIncoming) {
+ PhoneAccountHandle accountHandle = request.getAccountHandle();
+ if (accountHandle == null) {
+ throw new IllegalArgumentException("accountHandle must be specified.");
+ }
+
+ ComponentName componentName = request.getAccountHandle().getComponentName();
+ if (!mRemoteConnectionServices.containsKey(componentName)) {
+ throw new UnsupportedOperationException("accountHandle not supported: "
+ + componentName);
+ }
+
+ RemoteConnectionService remoteService = mRemoteConnectionServices.get(componentName);
+ if (remoteService != null) {
+ return remoteService.createRemoteConference(
+ connectionManagerPhoneAccount, request, isIncoming);
+ }
+ return null;
+ }
+
public void conferenceRemoteConnections(RemoteConnection a, RemoteConnection b) {
if (a.getConnectionService() == b.getConnectionService()) {
try {
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index a0833011715d..bf6a6ef793ff 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -31,9 +31,9 @@ import com.android.internal.telecom.RemoteServiceCallback;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.List;
import java.util.UUID;
/**
@@ -591,6 +591,38 @@ final class RemoteConnectionService {
}
}
+ RemoteConference createRemoteConference(
+ PhoneAccountHandle connectionManagerPhoneAccount,
+ ConnectionRequest request,
+ boolean isIncoming) {
+ final String id = UUID.randomUUID().toString();
+ try {
+ if (mConferenceById.isEmpty()) {
+ mOutgoingConnectionServiceRpc.addConnectionServiceAdapter(mServant.getStub(),
+ null /*Session.Info*/);
+ }
+ RemoteConference conference = new RemoteConference(id, mOutgoingConnectionServiceRpc);
+ mOutgoingConnectionServiceRpc.createConference(connectionManagerPhoneAccount,
+ id,
+ request,
+ isIncoming,
+ false /* isUnknownCall */,
+ null /*Session.info*/);
+ conference.registerCallback(new RemoteConference.Callback() {
+ @Override
+ public void onDestroyed(RemoteConference conference) {
+ mConferenceById.remove(id);
+ maybeDisconnectAdapter();
+ }
+ });
+ conference.putExtras(request.getExtras());
+ return conference;
+ } catch (RemoteException e) {
+ return RemoteConference.failure(
+ new DisconnectCause(DisconnectCause.ERROR, e.toString()));
+ }
+ }
+
private boolean hasConnection(String callId) {
return mConnectionById.containsKey(callId);
}
diff --git a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
index e57b03098758..d4308c4c30ad 100644
--- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
@@ -17,6 +17,7 @@
package com.android.internal.telephony;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -74,7 +75,7 @@ public final class CarrierAppUtils {
* privileged apps may have changed.
*/
public static synchronized void disableCarrierAppsUntilPrivileged(String callingPackage,
- TelephonyManager telephonyManager, int userId, Context context) {
+ TelephonyManager telephonyManager, @UserIdInt int userId, Context context) {
if (DEBUG) {
Log.d(TAG, "disableCarrierAppsUntilPrivileged");
}
@@ -101,7 +102,7 @@ public final class CarrierAppUtils {
* Manager can kill it, and this can lead to crashes as the app is in an unexpected state.
*/
public static synchronized void disableCarrierAppsUntilPrivileged(String callingPackage,
- int userId, Context context) {
+ @UserIdInt int userId, Context context) {
if (DEBUG) {
Log.d(TAG, "disableCarrierAppsUntilPrivileged");
}
@@ -117,9 +118,9 @@ public final class CarrierAppUtils {
systemCarrierAssociatedAppsDisabledUntilUsed, context);
}
- private static ContentResolver getContentResolverForUser(Context context, int userId) {
- Context userContext = context.createContextAsUser(UserHandle.getUserHandleForUid(userId),
- 0);
+ private static ContentResolver getContentResolverForUser(Context context,
+ @UserIdInt int userId) {
+ Context userContext = context.createContextAsUser(UserHandle.of(userId), 0);
return userContext.getContentResolver();
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 2b2608724e12..78dc377a303c 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -46,6 +46,7 @@ import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.ISms;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.SmsRawData;
+import com.android.telephony.Rlog;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -1953,7 +1954,6 @@ public final class SmsManager {
public boolean enableCellBroadcastRange(int startMessageId, int endMessageId,
@android.telephony.SmsCbMessage.MessageFormat int ranType) {
boolean success = false;
-
if (endMessageId < startMessageId) {
throw new IllegalArgumentException("endMessageId < startMessageId");
}
@@ -1962,10 +1962,14 @@ public final class SmsManager {
if (iSms != null) {
// If getSubscriptionId() returns INVALID or an inactive subscription, we will use
// the default phone internally.
- success = iSms.enableCellBroadcastRangeForSubscriber(getSubscriptionId(),
+ int subId = getSubscriptionId();
+ success = iSms.enableCellBroadcastRangeForSubscriber(subId,
startMessageId, endMessageId, ranType);
+ Rlog.d(TAG, "enableCellBroadcastRange: " + (success ? "succeeded" : "failed")
+ + " at calling enableCellBroadcastRangeForSubscriber. subId = " + subId);
}
} catch (RemoteException ex) {
+ Rlog.d(TAG, "enableCellBroadcastRange: " + ex.getStackTrace());
// ignore it
}
@@ -2019,10 +2023,14 @@ public final class SmsManager {
if (iSms != null) {
// If getSubscriptionId() returns INVALID or an inactive subscription, we will use
// the default phone internally.
- success = iSms.disableCellBroadcastRangeForSubscriber(getSubscriptionId(),
+ int subId = getSubscriptionId();
+ success = iSms.disableCellBroadcastRangeForSubscriber(subId,
startMessageId, endMessageId, ranType);
+ Rlog.d(TAG, "disableCellBroadcastRange: " + (success ? "succeeded" : "failed")
+ + " at calling disableCellBroadcastRangeForSubscriber. subId = " + subId);
}
} catch (RemoteException ex) {
+ Rlog.d(TAG, "disableCellBroadcastRange: " + ex.getStackTrace());
// ignore it
}
diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java
index 21bef001efae..9bf2f44395c4 100644
--- a/telephony/java/android/telephony/ims/ImsConferenceState.java
+++ b/telephony/java/android/telephony/ims/ImsConferenceState.java
@@ -203,10 +203,10 @@ public final class ImsConferenceState implements Parcelable {
for (String key : participantData.keySet()) {
sb.append(key);
sb.append("=");
- if (ENDPOINT.equals(key) || USER.equals(key)) {
- sb.append(Rlog.pii(TAG, participantData.get(key)));
- } else {
+ if (STATUS.equals(key)) {
sb.append(participantData.get(key));
+ } else {
+ sb.append(Rlog.pii(TAG, participantData.get(key)));
}
sb.append(", ");
}
diff --git a/tests/RollbackTest/README.txt b/tests/RollbackTest/README.txt
index c0b718a3e2c1..bc3b3bc3a1ee 100644
--- a/tests/RollbackTest/README.txt
+++ b/tests/RollbackTest/README.txt
@@ -9,10 +9,10 @@ StagedRollbackTest
- device driven test for staged rollbacks.
TestApp
- - source for dummy apks used in testing.
+ - source for fake apks used in testing.
TestApex
- - source for dummy apex modules used in testing.
+ - source for fake apex modules used in testing.
Running the tests
=================
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index 530d0e492f2e..76f8df02465b 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -18,6 +18,9 @@ android_test_helper_app {
srcs: ["app/src/**/*.java"],
static_libs: ["androidx.test.rules", "cts-install-lib"],
test_suites: ["general-tests"],
+ java_resources: [
+ ":com.android.apex.apkrollback.test_v2",
+ ],
}
java_test_host {
diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
index 02597d548361..12f1750fb78c 100644
--- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
@@ -49,6 +49,11 @@ import java.util.function.Consumer;
public class StagedInstallInternalTest {
private static final String TAG = StagedInstallInternalTest.class.getSimpleName();
+ private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test";
+ private static final TestApp TEST_APEX_WITH_APK_V1 = new TestApp("TestApexWithApkV1",
+ APK_IN_APEX_TESTAPEX_NAME, 1, /*isApex*/true, APK_IN_APEX_TESTAPEX_NAME + "_v1.apex");
+ private static final TestApp TEST_APEX_WITH_APK_V2 = new TestApp("TestApexWithApkV2",
+ APK_IN_APEX_TESTAPEX_NAME, 2, /*isApex*/true, APK_IN_APEX_TESTAPEX_NAME + "_v2.apex");
private File mTestStateFile = new File(
InstrumentationRegistry.getInstrumentation().getContext().getFilesDir(),
@@ -82,6 +87,24 @@ public class StagedInstallInternalTest {
}
@Test
+ public void testDuplicateApkInApexShouldFail_Commit() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ // Duplicate packages(TestApp.A) in TEST_APEX_WITH_APK_V2(apk-in-apex) and TestApp.A2(apk)
+ // should fail to install.
+ int sessionId = Install.multi(TEST_APEX_WITH_APK_V2, TestApp.A2).setStaged().commit();
+ storeSessionId(sessionId);
+ }
+
+ @Test
+ public void testDuplicateApkInApexShouldFail_Verify() throws Exception {
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ int sessionId = retrieveLastSessionId();
+ PackageInstaller.SessionInfo info =
+ InstallUtils.getPackageInstaller().getSessionInfo(sessionId);
+ assertThat(info.isStagedSessionFailed()).isTrue();
+ }
+
+ @Test
public void testSystemServerRestartDoesNotAffectStagedSessions_Commit() throws Exception {
int sessionId = Install.single(TestApp.A1).setStaged().commit();
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index 55def498a0cd..792e29d93be2 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -24,11 +24,14 @@ import static org.junit.Assume.assumeTrue;
import android.cts.install.lib.host.InstallUtilsHost;
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.ddmlib.Log;
import com.android.tests.rollback.host.AbandonSessionsRule;
import com.android.tests.util.ModuleTestUtils;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.ProcessInfo;
import org.junit.After;
@@ -49,6 +52,7 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test {
public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this);
private static final String SHIM_V2 = "com.android.apex.cts.shim.v2.apex";
private static final String APK_A = "TestAppAv1.apk";
+ private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test";
private final ModuleTestUtils mTestUtils = new ModuleTestUtils(this);
private final InstallUtilsHost mHostUtils = new InstallUtilsHost(this);
@@ -74,6 +78,8 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test {
} catch (AssertionError e) {
Log.e(TAG, e);
}
+ deleteFiles("/system/apex/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex",
+ "/data/apex/active/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex");
}
@Before
@@ -86,6 +92,55 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test {
cleanUp();
}
+ /**
+ * Deletes files and reboots the device if necessary.
+ * @param files the paths of files which might contain wildcards
+ */
+ private void deleteFiles(String... files) throws Exception {
+ boolean found = false;
+ for (String file : files) {
+ CommandResult result = getDevice().executeShellV2Command("ls " + file);
+ if (result.getStatus() == CommandStatus.SUCCESS) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ if (!getDevice().isAdbRoot()) {
+ getDevice().enableAdbRoot();
+ }
+ getDevice().remountSystemWritable();
+ for (String file : files) {
+ getDevice().executeShellCommand("rm -rf " + file);
+ }
+ getDevice().reboot();
+ }
+ }
+
+ private void pushTestApex() throws Exception {
+ CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
+ final String fileName = APK_IN_APEX_TESTAPEX_NAME + "_v1.apex";
+ final File apex = buildHelper.getTestFile(fileName);
+ if (!getDevice().isAdbRoot()) {
+ getDevice().enableAdbRoot();
+ }
+ getDevice().remountSystemWritable();
+ assertTrue(getDevice().pushFile(apex, "/system/apex/" + fileName));
+ getDevice().reboot();
+ }
+
+ /**
+ * Tests that duplicate packages in apk-in-apex and apk should fail to install.
+ */
+ @Test
+ public void testDuplicateApkInApexShouldFail() throws Exception {
+ pushTestApex();
+ runPhase("testDuplicateApkInApexShouldFail_Commit");
+ getDevice().reboot();
+ runPhase("testDuplicateApkInApexShouldFail_Verify");
+ }
+
@Test
public void testSystemServerRestartDoesNotAffectStagedSessions() throws Exception {
runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Commit");
diff --git a/tests/net/common/java/android/net/DhcpInfoTest.java b/tests/net/common/java/android/net/DhcpInfoTest.java
index 4d45ad72a9b8..ab4726bab573 100644
--- a/tests/net/common/java/android/net/DhcpInfoTest.java
+++ b/tests/net/common/java/android/net/DhcpInfoTest.java
@@ -17,8 +17,8 @@
package android.net;
import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTL;
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-import static com.android.testutils.ParcelUtilsKt.parcelingRoundTrip;
+import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
+import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/common/java/android/net/IpPrefixTest.java b/tests/net/common/java/android/net/IpPrefixTest.java
index 985e10df3961..9c0fc7ce7881 100644
--- a/tests/net/common/java/android/net/IpPrefixTest.java
+++ b/tests/net/common/java/android/net/IpPrefixTest.java
@@ -16,10 +16,10 @@
package android.net;
-import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.MiscAsserts.assertEqualBothWays;
+import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
+import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/common/java/android/net/LinkAddressTest.java b/tests/net/common/java/android/net/LinkAddressTest.java
index c74c112490f8..60308e32b88d 100644
--- a/tests/net/common/java/android/net/LinkAddressTest.java
+++ b/tests/net/common/java/android/net/LinkAddressTest.java
@@ -27,10 +27,10 @@ import static android.system.OsConstants.RT_SCOPE_LINK;
import static android.system.OsConstants.RT_SCOPE_SITE;
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
-import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.MiscAsserts.assertEqualBothWays;
+import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
+import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java
index 6eba62e63740..3c3076f11727 100644
--- a/tests/net/common/java/android/net/LinkPropertiesTest.java
+++ b/tests/net/common/java/android/net/LinkPropertiesTest.java
@@ -20,9 +20,9 @@ import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.RouteInfo.RTN_UNREACHABLE;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
-import static com.android.testutils.ParcelUtilsKt.parcelingRoundTrip;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
+import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
index 3f8261d5ad7f..e1693129892f 100644
--- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java
@@ -42,8 +42,8 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
import static android.net.NetworkCapabilities.UNRESTRICTED_CAPABILITIES;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/common/java/android/net/RouteInfoTest.java b/tests/net/common/java/android/net/RouteInfoTest.java
index 60cac0b6b0f5..71689f919726 100644
--- a/tests/net/common/java/android/net/RouteInfoTest.java
+++ b/tests/net/common/java/android/net/RouteInfoTest.java
@@ -18,10 +18,10 @@ package android.net;
import static android.net.RouteInfo.RTN_UNREACHABLE;
-import static com.android.testutils.MiscAssertsKt.assertEqualBothWays;
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-import static com.android.testutils.MiscAssertsKt.assertNotEqualEitherWay;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.MiscAsserts.assertEqualBothWays;
+import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
+import static com.android.testutils.MiscAsserts.assertNotEqualEitherWay;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
index 84805442e5c7..d50406fd3a1c 100644
--- a/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
+++ b/tests/net/common/java/android/net/apf/ApfCapabilitiesTest.java
@@ -16,7 +16,7 @@
package android.net.apf;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt b/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt
index fa2b99ce5cc6..165fd3728281 100644
--- a/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt
+++ b/tests/net/integration/util/com/android/server/ConnectivityServiceTestUtils.kt
@@ -14,6 +14,8 @@
* limitations under the License
*/
+@file:JvmName("ConnectivityServiceTestUtils")
+
package com.android.server
import android.net.ConnectivityManager.TYPE_BLUETOOTH
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index 0ffafd45613a..9f0b41fa0cdf 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -24,7 +24,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
-import static com.android.server.ConnectivityServiceTestUtilsKt.transportToLegacyType;
+import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType;
import static junit.framework.Assert.assertTrue;
@@ -49,7 +49,7 @@ import android.os.Message;
import android.util.Log;
import com.android.server.connectivity.ConnectivityConstants;
-import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.HandlerUtils;
import com.android.testutils.TestableNetworkCallback;
import java.util.Set;
@@ -265,6 +265,6 @@ public class NetworkAgentWrapper implements TestableNetworkCallback.HasNetwork {
}
public void waitForIdle(long timeoutMs) {
- HandlerUtilsKt.waitForIdle(mHandlerThread, timeoutMs);
+ HandlerUtils.waitForIdle(mHandlerThread, timeoutMs);
}
}
diff --git a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java b/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java
index 1d6c10766792..06e9405a6a79 100644
--- a/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityDiagnosticsManagerTest.java
@@ -21,7 +21,7 @@ import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnostics
import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
import static android.net.ConnectivityDiagnosticsManager.DataStallReport;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/java/android/net/IpSecConfigTest.java b/tests/net/java/android/net/IpSecConfigTest.java
index c9888b24b6da..25e225ef303a 100644
--- a/tests/net/java/android/net/IpSecConfigTest.java
+++ b/tests/net/java/android/net/IpSecConfigTest.java
@@ -16,8 +16,8 @@
package android.net;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index cea8c5713a6b..835a83e9ddc7 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -16,7 +16,7 @@
package android.net;
-import static com.android.testutils.ParcelUtilsKt.assertParcelingIsLossless;
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java b/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java
index efb92033df1e..6714bb1abbe6 100644
--- a/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java
+++ b/tests/net/java/android/net/TelephonyNetworkSpecifierTest.java
@@ -16,7 +16,7 @@
package android.net;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/java/android/net/nsd/NsdManagerTest.java b/tests/net/java/android/net/nsd/NsdManagerTest.java
index cf7587a2039f..b0a9b8a55322 100644
--- a/tests/net/java/android/net/nsd/NsdManagerTest.java
+++ b/tests/net/java/android/net/nsd/NsdManagerTest.java
@@ -38,7 +38,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.AsyncChannel;
-import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.HandlerUtils;
import org.junit.After;
import org.junit.Before;
@@ -73,7 +73,7 @@ public class NsdManagerTest {
@After
public void tearDown() throws Exception {
- HandlerUtilsKt.waitForIdle(mServiceHandler, mTimeoutMs);
+ HandlerUtils.waitForIdle(mServiceHandler, mTimeoutMs);
mServiceHandler.chan.disconnect();
mServiceHandler.stop();
if (mManager != null) {
@@ -333,7 +333,7 @@ public class NsdManagerTest {
}
int verifyRequest(int expectedMessageType) {
- HandlerUtilsKt.waitForIdle(mServiceHandler, mTimeoutMs);
+ HandlerUtils.waitForIdle(mServiceHandler, mTimeoutMs);
verify(mServiceHandler, timeout(mTimeoutMs)).handleMessage(any());
reset(mServiceHandler);
Message received = mServiceHandler.getLastMessage();
diff --git a/tests/net/java/com/android/internal/net/VpnProfileTest.java b/tests/net/java/com/android/internal/net/VpnProfileTest.java
index e5daa71c30ea..46597d19ef1b 100644
--- a/tests/net/java/com/android/internal/net/VpnProfileTest.java
+++ b/tests/net/java/com/android/internal/net/VpnProfileTest.java
@@ -16,7 +16,7 @@
package com.android.internal.net;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 0f24b0c1c79b..a3673df1c713 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -78,16 +78,16 @@ import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.IPPROTO_TCP;
-import static com.android.server.ConnectivityServiceTestUtilsKt.transportToLegacyType;
-import static com.android.testutils.ConcurrentUtilsKt.await;
-import static com.android.testutils.ConcurrentUtilsKt.durationOf;
+import static com.android.server.ConnectivityServiceTestUtils.transportToLegacyType;
+import static com.android.testutils.ConcurrentUtils.await;
+import static com.android.testutils.ConcurrentUtils.durationOf;
import static com.android.testutils.ExceptionUtils.ignoreExceptions;
-import static com.android.testutils.HandlerUtilsKt.waitForIdleSerialExecutor;
-import static com.android.testutils.MiscAssertsKt.assertContainsExactly;
-import static com.android.testutils.MiscAssertsKt.assertEmpty;
-import static com.android.testutils.MiscAssertsKt.assertLength;
-import static com.android.testutils.MiscAssertsKt.assertRunsInAtMost;
-import static com.android.testutils.MiscAssertsKt.assertThrows;
+import static com.android.testutils.HandlerUtils.waitForIdleSerialExecutor;
+import static com.android.testutils.MiscAsserts.assertContainsExactly;
+import static com.android.testutils.MiscAsserts.assertEmpty;
+import static com.android.testutils.MiscAsserts.assertLength;
+import static com.android.testutils.MiscAsserts.assertRunsInAtMost;
+import static com.android.testutils.MiscAsserts.assertThrows;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -242,7 +242,7 @@ import com.android.server.connectivity.Vpn;
import com.android.server.net.NetworkPinner;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.testutils.ExceptionUtils;
-import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.HandlerUtils;
import com.android.testutils.RecorderCallback.CallbackEntry;
import com.android.testutils.TestableNetworkCallback;
@@ -518,12 +518,12 @@ public class ConnectivityServiceTest {
}
private void waitForIdle() {
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
waitForIdle(mCellNetworkAgent, TIMEOUT_MS);
waitForIdle(mWiFiNetworkAgent, TIMEOUT_MS);
waitForIdle(mEthernetNetworkAgent, TIMEOUT_MS);
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
- HandlerUtilsKt.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS);
}
private void waitForIdle(TestNetworkAgentWrapper agent, long timeoutMs) {
@@ -614,8 +614,8 @@ public class ConnectivityServiceTest {
// Waits for the NetworkAgent to be registered, which includes the creation of the
// NetworkMonitor.
waitForIdle(TIMEOUT_MS);
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
- HandlerUtilsKt.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS);
}
@Override
@@ -7099,7 +7099,7 @@ public class ConnectivityServiceTest {
mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName());
// Block until all other events are done processing.
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
verify(mConnectivityDiagnosticsCallback).asBinder();
@@ -7122,7 +7122,7 @@ public class ConnectivityServiceTest {
mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName());
// Block until all other events are done processing.
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
verify(mIBinder).linkToDeath(any(ConnectivityDiagnosticsCallbackInfo.class), anyInt());
verify(mConnectivityDiagnosticsCallback).asBinder();
@@ -7133,7 +7133,7 @@ public class ConnectivityServiceTest {
mConnectivityDiagnosticsCallback, wifiRequest, mContext.getPackageName());
// Block until all other events are done processing.
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
assertTrue(mService.mConnectivityDiagnosticsCallbacks.containsKey(mIBinder));
}
@@ -7285,7 +7285,7 @@ public class ConnectivityServiceTest {
mConnectivityDiagnosticsCallback, request, mContext.getPackageName());
// Block until all other events are done processing.
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
verify(mConnectivityDiagnosticsCallback)
.onConnectivityReportAvailable(argThat(report -> {
@@ -7305,7 +7305,7 @@ public class ConnectivityServiceTest {
mConnectivityDiagnosticsCallback, request, mContext.getPackageName());
// Block until all other events are done processing.
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
// Connect the cell agent verify that it notifies TestNetworkCallback that it is available
final TestNetworkCallback callback = new TestNetworkCallback();
@@ -7322,7 +7322,7 @@ public class ConnectivityServiceTest {
setUpConnectivityDiagnosticsCallback();
// Block until all other events are done processing.
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
// Verify onConnectivityReport fired
verify(mConnectivityDiagnosticsCallback).onConnectivityReportAvailable(
@@ -7343,7 +7343,7 @@ public class ConnectivityServiceTest {
mCellNetworkAgent.notifyDataStallSuspected();
// Block until all other events are done processing.
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
// Verify onDataStallSuspected fired
verify(mConnectivityDiagnosticsCallback).onDataStallSuspected(
@@ -7364,7 +7364,7 @@ public class ConnectivityServiceTest {
mService.reportNetworkConnectivity(n, hasConnectivity);
// Block until all other events are done processing.
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
// Verify onNetworkConnectivityReported fired
verify(mConnectivityDiagnosticsCallback)
@@ -7374,7 +7374,7 @@ public class ConnectivityServiceTest {
mService.reportNetworkConnectivity(n, noConnectivity);
// Block until all other events are done processing.
- HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
// Wait for onNetworkConnectivityReported to fire
verify(mConnectivityDiagnosticsCallback)
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
index 508b5cd9cb19..753dbf80b449 100644
--- a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -26,9 +26,9 @@ import static android.provider.Settings.Global.PRIVATE_DNS_DEFAULT_MODE;
import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
-import static com.android.testutils.MiscAssertsKt.assertContainsExactly;
-import static com.android.testutils.MiscAssertsKt.assertContainsStringsExactly;
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
+import static com.android.testutils.MiscAsserts.assertContainsExactly;
+import static com.android.testutils.MiscAsserts.assertContainsStringsExactly;
+import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
index aef9386755d7..8ccea1aa3474 100644
--- a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -19,7 +19,7 @@ package com.android.server.connectivity;
import static android.net.metrics.INetdEventListener.EVENT_GETADDRINFO;
import static android.net.metrics.INetdEventListener.EVENT_GETHOSTBYNAME;
-import static com.android.testutils.MiscAssertsKt.assertStringContains;
+import static com.android.testutils.MiscAsserts.assertStringContains;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index a384687e06f6..ab12ac0ef56e 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -28,11 +28,17 @@ import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
+import static android.net.INetd.PERMISSION_INTERNET;
+import static android.net.INetd.PERMISSION_NONE;
+import static android.net.INetd.PERMISSION_SYSTEM;
+import static android.net.INetd.PERMISSION_UNINSTALLED;
+import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.Process.SYSTEM_UID;
import static com.android.server.connectivity.PermissionMonitor.NETWORK;
import static com.android.server.connectivity.PermissionMonitor.SYSTEM;
+import static com.android.server.connectivity.PermissionMonitor.UidNetdPermissionInfo;
import static junit.framework.Assert.fail;
@@ -63,7 +69,7 @@ import android.net.UidRange;
import android.os.Build;
import android.os.UserHandle;
import android.os.UserManager;
-import android.util.SparseIntArray;
+import android.util.SparseArray;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -312,7 +318,7 @@ public class PermissionMonitorTest {
// Add hook to verify and track result of setPermission.
doAnswer((InvocationOnMock invocation) -> {
final Object[] args = invocation.getArguments();
- final Boolean isSystem = args[0].equals(INetd.PERMISSION_SYSTEM);
+ final Boolean isSystem = args[0].equals(PERMISSION_SYSTEM);
for (final int uid : (int[]) args[1]) {
// TODO: Currently, permission monitor will send duplicate commands for each uid
// corresponding to each user. Need to fix that and uncomment below test.
@@ -555,39 +561,40 @@ public class PermissionMonitorTest {
// SYSTEM_UID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission.
// SYSTEM_UID2: SYSTEM_PACKAGE2 has only update device stats permission.
- SparseIntArray netdPermissionsAppIds = new SparseIntArray();
- netdPermissionsAppIds.put(MOCK_UID1, INetd.PERMISSION_INTERNET);
- netdPermissionsAppIds.put(MOCK_UID2, INetd.PERMISSION_NONE);
- netdPermissionsAppIds.put(SYSTEM_UID1, INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS);
- netdPermissionsAppIds.put(SYSTEM_UID2, INetd.PERMISSION_UPDATE_DEVICE_STATS);
+ final SparseArray<UidNetdPermissionInfo> uidsPermInfo = new SparseArray<>();
+ uidsPermInfo.put(MOCK_UID1, new UidNetdPermissionInfo(PERMISSION_INTERNET));
+ uidsPermInfo.put(MOCK_UID2, new UidNetdPermissionInfo(PERMISSION_NONE));
+ uidsPermInfo.put(SYSTEM_UID1, new UidNetdPermissionInfo(
+ PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS));
+ uidsPermInfo.put(SYSTEM_UID2, new UidNetdPermissionInfo(PERMISSION_UPDATE_DEVICE_STATS));
// Send the permission information to netd, expect permission updated.
- mPermissionMonitor.sendPackagePermissionsToNetd(netdPermissionsAppIds);
+ mPermissionMonitor.sendPackagePermissionsToNetd(uidsPermInfo);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET,
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET,
new int[]{MOCK_UID1});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID2});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{SYSTEM_UID1});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UPDATE_DEVICE_STATS,
+ mNetdServiceMonitor.expectPermission(PERMISSION_NONE, new int[]{MOCK_UID2});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET
+ | PERMISSION_UPDATE_DEVICE_STATS, new int[]{SYSTEM_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_UPDATE_DEVICE_STATS,
new int[]{SYSTEM_UID2});
// Update permission of MOCK_UID1, expect new permission show up.
- mPermissionMonitor.sendPackagePermissionsForUid(MOCK_UID1,
- INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mPermissionMonitor.sendPackagePermissionsForUid(MOCK_UID1, new UidNetdPermissionInfo(
+ PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS));
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET
+ | PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
// Change permissions of SYSTEM_UID2, expect new permission show up and old permission
// revoked.
- mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID2,
- INetd.PERMISSION_INTERNET);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{SYSTEM_UID2});
+ mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID2, new UidNetdPermissionInfo(
+ PERMISSION_INTERNET));
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET, new int[]{SYSTEM_UID2});
// Revoke permission from SYSTEM_UID1, expect no permission stored.
- mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID1, INetd.PERMISSION_NONE);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{SYSTEM_UID1});
+ mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID1, new UidNetdPermissionInfo(
+ PERMISSION_NONE));
+ mNetdServiceMonitor.expectPermission(PERMISSION_NONE, new int[]{SYSTEM_UID1});
}
private PackageInfo setPackagePermissions(String packageName, int uid, String[] permissions)
@@ -611,11 +618,11 @@ public class PermissionMonitorTest {
final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET
+ | PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
addPackage(MOCK_PACKAGE2, MOCK_UID2, new String[] {INTERNET});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID2});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET, new int[]{MOCK_UID2});
}
@Test
@@ -623,8 +630,8 @@ public class PermissionMonitorTest {
final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET
+ | PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
// Install another package with the same uid and no permissions should not cause the UID to
// lose permissions.
@@ -633,8 +640,8 @@ public class PermissionMonitorTest {
when(mPackageManager.getPackagesForUid(MOCK_UID1))
.thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
mPermissionMonitor.onPackageAdded(MOCK_PACKAGE2, MOCK_UID1);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET
+ | PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
}
@Test
@@ -642,12 +649,12 @@ public class PermissionMonitorTest {
final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET
+ | PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
}
@Test
@@ -655,16 +662,16 @@ public class PermissionMonitorTest {
final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET
+ | PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
removeAllPermissions(MOCK_UID1);
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET, new int[]{MOCK_UID1});
}
@Test
@@ -672,10 +679,10 @@ public class PermissionMonitorTest {
final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_NONE, new int[]{MOCK_UID1});
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET, new int[]{MOCK_UID1});
}
@Test
@@ -683,8 +690,8 @@ public class PermissionMonitorTest {
final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
- | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET
+ | PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
// Mock another package with the same uid but different permissions.
final PackageInfo packageInfo2 = buildPackageInfo(PARTITION_SYSTEM, MOCK_UID1, MOCK_USER1);
@@ -695,7 +702,7 @@ public class PermissionMonitorTest {
addPermissions(MOCK_UID1, INTERNET);
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+ mNetdServiceMonitor.expectPermission(PERMISSION_INTERNET, new int[]{MOCK_UID1});
}
@Test
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index de1c5759ee87..e8c4ee9c628d 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -270,12 +270,12 @@ public class VpnTest {
}
@Test
- public void testUidWhiteAndBlacklist() throws Exception {
+ public void testUidAllowAndDenylist() throws Exception {
final Vpn vpn = createVpn(primaryUser.id);
final UidRange user = UidRange.createForUser(primaryUser.id);
final String[] packages = {PKGS[0], PKGS[1], PKGS[2]};
- // Whitelist
+ // Allowed list
final Set<UidRange> allow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
Arrays.asList(packages), null);
assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
@@ -283,7 +283,7 @@ public class VpnTest {
new UidRange(user.start + PKG_UIDS[1], user.start + PKG_UIDS[2])
})), allow);
- // Blacklist
+ // Denied list
final Set<UidRange> disallow = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
null, Arrays.asList(packages));
assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
@@ -354,11 +354,11 @@ public class VpnTest {
}
@Test
- public void testLockdownWhitelist() throws Exception {
+ public void testLockdownAllowlist() throws Exception {
final Vpn vpn = createVpn(primaryUser.id);
final UidRange user = UidRange.createForUser(primaryUser.id);
- // Set always-on with lockdown and whitelist app PKGS[2] from lockdown.
+ // Set always-on with lockdown and allow app PKGS[2] from lockdown.
assertTrue(vpn.setAlwaysOnPackage(
PKGS[1], true, Collections.singletonList(PKGS[2]), mKeyStore));
verify(mNetService).setAllowOnlyVpnForUids(eq(true), aryEq(new UidRange[] {
@@ -368,7 +368,7 @@ public class VpnTest {
assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[3]);
assertUnblocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
- // Change whitelisted app to PKGS[3].
+ // Change allowed app list to PKGS[3].
assertTrue(vpn.setAlwaysOnPackage(
PKGS[1], true, Collections.singletonList(PKGS[3]), mKeyStore));
verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
@@ -395,7 +395,7 @@ public class VpnTest {
assertBlocked(vpn, user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[3]);
- // Remove the whitelist.
+ // Remove the list of allowed packages.
assertTrue(vpn.setAlwaysOnPackage(PKGS[0], true, null, mKeyStore));
verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
new UidRange(user.start + PKG_UIDS[0] + 1, user.start + PKG_UIDS[3] - 1),
@@ -408,7 +408,7 @@ public class VpnTest {
user.start + PKG_UIDS[3]);
assertUnblocked(vpn, user.start + PKG_UIDS[0]);
- // Add the whitelist.
+ // Add the list of allowed packages.
assertTrue(vpn.setAlwaysOnPackage(
PKGS[0], true, Collections.singletonList(PKGS[1]), mKeyStore));
verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[] {
@@ -421,12 +421,12 @@ public class VpnTest {
assertBlocked(vpn, user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1]);
- // Try whitelisting a package with a comma, should be rejected.
+ // Try allowing a package with a comma, should be rejected.
assertFalse(vpn.setAlwaysOnPackage(
PKGS[0], true, Collections.singletonList("a.b,c.d"), mKeyStore));
- // Pass a non-existent packages in the whitelist, they (and only they) should be ignored.
- // Whitelisted package should change from PGKS[1] to PKGS[2].
+ // Pass a non-existent packages in the allowlist, they (and only they) should be ignored.
+ // allowed package should change from PGKS[1] to PKGS[2].
assertTrue(vpn.setAlwaysOnPackage(
PKGS[0], true, Arrays.asList("com.foo.app", PKGS[2], "com.bar.app"), mKeyStore));
verify(mNetService).setAllowOnlyVpnForUids(eq(false), aryEq(new UidRange[]{
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index e83d2a90bffa..fb0cfc0d50ba 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -28,7 +28,7 @@ import static android.os.Process.myUid;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
-import static com.android.testutils.MiscAssertsKt.assertThrows;
+import static com.android.testutils.MiscAsserts.assertThrows;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
index a6f7a36ff01b..291efc74aa47 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -53,7 +53,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.net.NetworkStatsServiceTest.LatchedHandler;
-import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.HandlerUtils;
import org.junit.Before;
import org.junit.Test;
@@ -440,7 +440,7 @@ public class NetworkStatsObserversTest {
}
private void waitForObserverToIdle() {
- HandlerUtilsKt.waitForIdle(mObserverHandlerThread, WAIT_TIMEOUT_MS);
- HandlerUtilsKt.waitForIdle(mHandler, WAIT_TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mObserverHandlerThread, WAIT_TIMEOUT_MS);
+ HandlerUtils.waitForIdle(mHandler, WAIT_TIMEOUT_MS);
}
}
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 1307a849f1eb..7abe1893dd9e 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -109,7 +109,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
-import com.android.testutils.HandlerUtilsKt;
+import com.android.testutils.HandlerUtils;
import com.android.testutils.TestableNetworkStatsProviderBinder;
import libcore.io.IoUtils;
@@ -700,7 +700,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString()))
.thenReturn(ratType);
mService.handleOnCollapsedRatTypeChanged();
- HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
+ HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
}
@Test
@@ -1065,7 +1065,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
long minThresholdInBytes = 2 * 1024 * 1024; // 2 MB
assertEquals(minThresholdInBytes, request.thresholdInBytes);
- HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
+ HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
// Make sure that the caller binder gets connected
verify(mBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
@@ -1203,7 +1203,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// Simulates alert quota of the provider has been reached.
cb.notifyAlertReached();
- HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
+ HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
// Verifies that polling is triggered by alert reached.
provider.expectOnRequestStatsUpdate(0 /* unused */);
@@ -1264,7 +1264,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// Call handleOnCollapsedRatTypeChanged manually to simulate the callback fired
// when stopping monitor, this is needed by NetworkStatsService to trigger updateIfaces.
mService.handleOnCollapsedRatTypeChanged();
- HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
+ HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
// Append more traffic on existing snapshot.
@@ -1286,7 +1286,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
setCombineSubtypeEnabled(false);
mService.handleOnCollapsedRatTypeChanged();
- HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
+ HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
// Append more traffic on existing snapshot.
@@ -1520,7 +1520,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
}
private void waitForIdle() {
- HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
+ HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
}
static class LatchedHandler extends Handler {
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index 8a282e5f0821..da644021e30e 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -34,26 +34,6 @@ FLAG_PUBLIC_API = 'public-api'
FLAG_SYSTEM_API = 'system-api'
FLAG_TEST_API = 'test-api'
-OLD_FLAG_SDK = "whitelist"
-OLD_FLAG_UNSUPPORTED = "greylist"
-OLD_FLAG_BLOCKED = "blacklist"
-OLD_FLAG_MAX_TARGET_O = "greylist-max-o"
-OLD_FLAG_MAX_TARGET_P = "greylist-max-p"
-OLD_FLAG_MAX_TARGET_Q = "greylist-max-q"
-OLD_FLAG_MAX_TARGET_R = "greylist-max-r"
-
-OLD_FLAGS_TO_NEW = {
- OLD_FLAG_SDK: FLAG_SDK,
- OLD_FLAG_UNSUPPORTED: FLAG_UNSUPPORTED,
- OLD_FLAG_BLOCKED: FLAG_BLOCKED,
- OLD_FLAG_MAX_TARGET_O: FLAG_MAX_TARGET_O,
- OLD_FLAG_MAX_TARGET_P: FLAG_MAX_TARGET_P,
- OLD_FLAG_MAX_TARGET_Q: FLAG_MAX_TARGET_Q,
- OLD_FLAG_MAX_TARGET_R: FLAG_MAX_TARGET_R,
-}
-
-NEW_FLAGS_TO_OLD = dict(zip(OLD_FLAGS_TO_NEW.values(), OLD_FLAGS_TO_NEW.keys()))
-
# List of all known flags.
FLAGS_API_LIST = [
FLAG_SDK,
@@ -205,36 +185,6 @@ class FlagsDict:
"Please visit go/hiddenapi for more information.").format(
source, "\n".join(flags_subset - ALL_FLAGS_SET))
- def convert_to_new_flag(self, flag):
- """Converts old flag to a new variant.
-
- Flags that are considered old are replaced with new versions.
- Otherwise, it is a no-op.
-
- Args:
- flag: a string, representing SDK flag.
-
- Returns:
- A string. Result of conversion.
-
- """
- return OLD_FLAGS_TO_NEW.get(flag, flag)
-
- def convert_to_old_flag(self, flag):
- """Converts a new flag to a old variant.
-
- No-op if there is no suitable old flag.
- Only used to support backwards compatibility.
-
- Args:
- flag: a string, representing SDK flag.
-
- Returns:
- A string. Result of conversion.
-
- """
- return NEW_FLAGS_TO_OLD.get(flag, flag)
-
def filter_apis(self, filter_fn):
"""Returns APIs which match a given predicate.
@@ -272,7 +222,7 @@ class FlagsDict:
"""
lines = []
for api in self._dict:
- flags = sorted([self.convert_to_old_flag(flag) for flag in self._dict[api]])
+ flags = sorted(self._dict[api])
lines.append(",".join([api] + flags))
return sorted(lines)
@@ -298,12 +248,12 @@ class FlagsDict:
# Check that all flags are known.
csv_flags = set()
for csv in csv_values:
- csv_flags.update([self.convert_to_new_flag(flag) for flag in csv[1:]])
+ csv_flags.update(csv[1:])
self._check_flags_set(csv_flags, source)
# Iterate over all CSV lines, find entry in dict and append flags to it.
for csv in csv_values:
- flags = [self.convert_to_new_flag(flag) for flag in csv[1:]]
+ flags = csv[1:]
if (FLAG_PUBLIC_API in flags) or (FLAG_SYSTEM_API in flags):
flags.append(FLAG_SDK)
self._dict[csv[0]].update(flags)
diff --git a/tools/hiddenapi/generate_hiddenapi_lists_test.py b/tools/hiddenapi/generate_hiddenapi_lists_test.py
index 321c400ef898..82d117fbbbab 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists_test.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists_test.py
@@ -35,7 +35,7 @@ class TestHiddenapiListGeneration(unittest.TestCase):
flags.parse_and_merge_csv(['A,' + FLAG_SDK, 'B', 'C'])
flags.assign_flag(FLAG_UNSUPPORTED, set(['C']))
self.assertEqual(flags.generate_csv(),
- [ 'A,' + OLD_FLAG_SDK, 'B', 'C,' + OLD_FLAG_UNSUPPORTED ])
+ [ 'A,' + FLAG_SDK, 'B', 'C,' + FLAG_UNSUPPORTED ])
# Check three things:
# (1) B is selected as valid unassigned
@@ -50,8 +50,7 @@ class TestHiddenapiListGeneration(unittest.TestCase):
# Test empty CSV entry.
self.assertEqual(flags.generate_csv(), [])
- # Test new additions. CSV generator produces values with old flags
- # to be backwards compatible.
+ # Test new additions.
flags.parse_and_merge_csv([
'A,' + FLAG_UNSUPPORTED,
'B,' + FLAG_BLOCKED + ',' + FLAG_MAX_TARGET_O,
@@ -60,11 +59,11 @@ class TestHiddenapiListGeneration(unittest.TestCase):
'E,' + FLAG_BLOCKED + ',' + FLAG_TEST_API,
])
self.assertEqual(flags.generate_csv(), [
- 'A,' + OLD_FLAG_UNSUPPORTED,
- 'B,' + OLD_FLAG_BLOCKED + "," + OLD_FLAG_MAX_TARGET_O,
- 'C,' + FLAG_SYSTEM_API + ',' + OLD_FLAG_SDK,
- 'D,' + OLD_FLAG_UNSUPPORTED + ',' + FLAG_TEST_API,
- 'E,' + OLD_FLAG_BLOCKED + ',' + FLAG_TEST_API,
+ 'A,' + FLAG_UNSUPPORTED,
+ 'B,' + FLAG_BLOCKED + "," + FLAG_MAX_TARGET_O,
+ 'C,' + FLAG_SYSTEM_API + ',' + FLAG_SDK,
+ 'D,' + FLAG_UNSUPPORTED + ',' + FLAG_TEST_API,
+ 'E,' + FLAG_BLOCKED + ',' + FLAG_TEST_API,
])
# Test unknown flag.
@@ -78,7 +77,7 @@ class TestHiddenapiListGeneration(unittest.TestCase):
# Test new additions.
flags.assign_flag(FLAG_UNSUPPORTED, set([ 'A', 'B' ]))
self.assertEqual(flags.generate_csv(),
- [ 'A,' + OLD_FLAG_UNSUPPORTED + "," + OLD_FLAG_SDK, 'B,' + OLD_FLAG_UNSUPPORTED ])
+ [ 'A,' + FLAG_UNSUPPORTED + "," + FLAG_SDK, 'B,' + FLAG_UNSUPPORTED ])
# Test invalid API signature.
with self.assertRaises(AssertionError):
diff --git a/wifi/java/android/net/wifi/SoftApConfiguration.java b/wifi/java/android/net/wifi/SoftApConfiguration.java
index f919ea4c4797..393fe8d3ab9a 100644
--- a/wifi/java/android/net/wifi/SoftApConfiguration.java
+++ b/wifi/java/android/net/wifi/SoftApConfiguration.java
@@ -582,6 +582,7 @@ public final class SoftApConfiguration implements Parcelable {
wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
break;
case SECURITY_TYPE_WPA2_PSK:
+ case SECURITY_TYPE_WPA3_SAE_TRANSITION:
wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
break;
default:
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
index fa806e7797cd..282757ac5a14 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -448,6 +448,16 @@ public final class Credential implements Parcelable {
return new UserCredential[size];
}
};
+
+ /**
+ * Get a unique identifier for UserCredential.
+ *
+ * @hide
+ * @return a Unique identifier for a UserCredential object
+ */
+ public int getUniqueId() {
+ return Objects.hash(mUsername);
+ }
}
private UserCredential mUserCredential = null;
/**
@@ -1037,7 +1047,8 @@ public final class Credential implements Parcelable {
* @return a Unique identifier for a Credential object
*/
public int getUniqueId() {
- return Objects.hash(mUserCredential, mCertCredential, mSimCredential, mRealm);
+ return Objects.hash(mUserCredential != null ? mUserCredential.getUniqueId() : 0,
+ mCertCredential, mSimCredential, mRealm);
}
@Override
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
index 224c4bed9d5b..8f34579f6a5d 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
@@ -313,9 +313,7 @@ public final class HomeSp implements Parcelable {
* @return a Unique identifier for a HomeSp object
*/
public int getUniqueId() {
- return Objects.hash(mFqdn, mFriendlyName, mHomeNetworkIds, Arrays.hashCode(mMatchAllOis),
- Arrays.hashCode(mMatchAnyOis), Arrays.hashCode(mOtherHomePartners),
- Arrays.hashCode(mRoamingConsortiumOis));
+ return Objects.hash(mFqdn);
}
diff --git a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
index bfdd45d9f9b0..fd89d3b0486e 100644
--- a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
+++ b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl
@@ -25,7 +25,7 @@ import android.os.Messenger;
*/
interface IWifiP2pManager
{
- Messenger getMessenger(in IBinder binder);
+ Messenger getMessenger(in IBinder binder, in String packageName);
Messenger getP2pStateMachineMessenger();
oneway void close(in IBinder binder);
void setMiracastMode(int mode);
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 724ccf0d7c45..ad38c5af07fc 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -1156,8 +1156,8 @@ public class WifiP2pManager {
*/
public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
Binder binder = new Binder();
- Channel channel = initalizeChannel(srcContext, srcLooper, listener, getMessenger(binder),
- binder);
+ Channel channel = initializeChannel(srcContext, srcLooper, listener,
+ getMessenger(binder, srcContext.getOpPackageName()), binder);
return channel;
}
@@ -1167,12 +1167,12 @@ public class WifiP2pManager {
*/
public Channel initializeInternal(Context srcContext, Looper srcLooper,
ChannelListener listener) {
- return initalizeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger(),
+ return initializeChannel(srcContext, srcLooper, listener, getP2pStateMachineMessenger(),
null);
}
- private Channel initalizeChannel(Context srcContext, Looper srcLooper, ChannelListener listener,
- Messenger messenger, Binder binder) {
+ private Channel initializeChannel(Context srcContext, Looper srcLooper,
+ ChannelListener listener, Messenger messenger, Binder binder) {
if (messenger == null) return null;
Channel c = new Channel(srcContext, srcLooper, listener, binder, this);
@@ -1814,6 +1814,14 @@ public class WifiP2pManager {
}
}
+ private Messenger getMessenger(@NonNull Binder binder, @Nullable String packageName) {
+ try {
+ return mService.getMessenger(binder, packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
/**
* Get a reference to WifiP2pService handler. This is used to establish
* an AsyncChannel communication with WifiService
@@ -1824,11 +1832,8 @@ public class WifiP2pManager {
* @hide
*/
public Messenger getMessenger(Binder binder) {
- try {
- return mService.getMessenger(binder);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ // No way to determine package name in this case.
+ return getMessenger(binder, null);
}
/**
diff --git a/wifi/tests/src/android/net/wifi/FakeKeys.java b/wifi/tests/src/android/net/wifi/FakeKeys.java
index c0d60c33f99c..641b891a1f4d 100644
--- a/wifi/tests/src/android/net/wifi/FakeKeys.java
+++ b/wifi/tests/src/android/net/wifi/FakeKeys.java
@@ -214,6 +214,35 @@ public class FakeKeys {
};
public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1);
+ private static final String CLIENT_SUITE_B_RSA3072_CERT_STRING =
+ "-----BEGIN CERTIFICATE-----\n"
+ + "MIIERzCCAq8CFDopjyNgaj+c2TN2k06h7okEWpHJMA0GCSqGSIb3DQEBDAUAMF4x\n"
+ + "CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQK\n"
+ + "DAdBbmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4X\n"
+ + "DTIwMDcyMTAyMjkxMVoXDTMwMDUzMDAyMjkxMVowYjELMAkGA1UEBhMCVVMxCzAJ\n"
+ + "BgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNV\n"
+ + "BAsMBVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MIIBojANBgkqhkiG9w0B\n"
+ + "AQEFAAOCAY8AMIIBigKCAYEAwSK3C5K5udtCKTnE14e8z2cZvwmB4Xe+a8+7QLud\n"
+ + "Hooc/lQzClgK4MbVUC0D3FE+U32C78SxKoTaRWtvPmNm+UaFT8KkwyUno/dv+2XD\n"
+ + "pd/zARQ+3FwAfWopAhEyCVSxwsCa+slQ4juRIMIuUC1Mm0NaptZyM3Tj/ICQEfpk\n"
+ + "o9qVIbiK6eoJMTkY8EWfAn7RTFdfR1OLuO0mVOjgLW9/+upYv6hZ19nAMAxw4QTJ\n"
+ + "x7lLwALX7B+tDYNEZHDqYL2zyvQWAj2HClere8QYILxkvktgBg2crEJJe4XbDH7L\n"
+ + "A3rrXmsiqf1ZbfFFEzK9NFqovL+qGh+zIP+588ShJFO9H/RDnDpiTnAFTWXQdTwg\n"
+ + "szSS0Vw2PB+JqEABAa9DeMvXT1Oy+NY3ItPHyy63nQZVI2rXANw4NhwS0Z6DF+Qs\n"
+ + "TNrj+GU7e4SG/EGR8SvldjYfQTWFLg1l/UT1hOOkQZwdsaW1zgKyeuiFB2KdMmbA\n"
+ + "Sq+Ux1L1KICo0IglwWcB/8nnAgMBAAEwDQYJKoZIhvcNAQEMBQADggGBAMYwJkNw\n"
+ + "BaCviKFmReDTMwWPRy4AMNViEeqAXgERwDEKwM7efjsaj5gctWfKsxX6UdLzkhgg\n"
+ + "6S/T6PxVWKzJ6l7SoOuTa6tMQOZp+h3R1mdfEQbw8B5cXBxZ+batzAai6Fiy1FKS\n"
+ + "/ka3INbcGfYuIYghfTrb4/NJKN06ZaQ1bpPwq0e4gN7800T2nbawvSf7r+8ZLcG3\n"
+ + "6bGCjRMwDSIipNvOwoj3TG315XC7TccX5difQ4sKOY+d2MkVJ3RiO0Ciw2ZbEW8d\n"
+ + "1FH5vUQJWnBUfSFznosGzLwH3iWfqlP+27jNE+qB2igEwCRFgVAouURx5ou43xuX\n"
+ + "qf6JkdI3HTJGLIWxkp7gOeln4dEaYzKjYw+P0VqJvKVqQ0IXiLjHgE0J9p0vgyD6\n"
+ + "HVVcP7U8RgqrbIjL1QgHU4KBhGi+WSUh/mRplUCNvHgcYdcHi/gHpj/j6ubwqIGV\n"
+ + "z4iSolAHYTmBWcLyE0NgpzE6ntp+53r2KaUJA99l2iGVzbWTwqPSm0XAVw==\n"
+ + "-----END CERTIFICATE-----\n";
+ public static final X509Certificate CLIENT_SUITE_B_RSA3072_CERT =
+ loadCertificate(CLIENT_SUITE_B_RSA3072_CERT_STRING);
+
private static X509Certificate loadCertificate(String blob) {
try {
final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
diff --git a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
index c2d0d6d81e84..254434b81f8f 100644
--- a/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/SoftApConfigurationTest.java
@@ -310,12 +310,6 @@ public class SoftApConfigurationTest {
.build();
assertNull(band_6g_config.toWifiConfiguration());
- SoftApConfiguration sae_transition_config = new SoftApConfiguration.Builder()
- .setPassphrase("secretsecret",
- SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
- .build();
-
- assertNull(sae_transition_config.toWifiConfiguration());
}
@Test
@@ -358,5 +352,16 @@ public class SoftApConfigurationTest {
assertThat(wifiConfig_2g5g.apBand).isEqualTo(WifiConfiguration.AP_BAND_ANY);
assertThat(wifiConfig_2g5g.apChannel).isEqualTo(0);
assertThat(wifiConfig_2g5g.hiddenSSID).isEqualTo(true);
+
+ SoftApConfiguration softApConfig_sae_transition = new SoftApConfiguration.Builder()
+ .setPassphrase("secretsecret",
+ SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION)
+ .build();
+
+ WifiConfiguration wifiConfig_sae_transition =
+ softApConfig_sae_transition.toWifiConfiguration();
+ assertThat(wifiConfig_sae_transition.getAuthType())
+ .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
+ assertThat(wifiConfig_sae_transition.preSharedKey).isEqualTo("secretsecret");
}
}
diff --git a/wifi/tests/src/android/net/wifi/WifiClientTest.java b/wifi/tests/src/android/net/wifi/WifiClientTest.java
index 42cab55305b9..7a3baf9ebaf2 100644
--- a/wifi/tests/src/android/net/wifi/WifiClientTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiClientTest.java
@@ -16,8 +16,8 @@
package android.net.wifi;
-import static com.android.testutils.MiscAssertsKt.assertFieldCountEquals;
-import static com.android.testutils.ParcelUtilsKt.assertParcelSane;
+import static com.android.testutils.MiscAsserts.assertFieldCountEquals;
+import static com.android.testutils.ParcelUtils.assertParcelSane;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
index 638efb9f14ee..8270d643ca65 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
+import android.net.wifi.EAPConstants;
+import android.net.wifi.FakeKeys;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.Parcel;
@@ -32,6 +34,11 @@ import androidx.test.filters.SmallTest;
import org.junit.Test;
import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -383,19 +390,39 @@ public class PasspointConfigurationTest {
}
/**
- * Verify that the unique identifier generated is different for two instances with different
- * HomeSp node
+ * Verify that the unique identifier generated is the same for two instances with different
+ * HomeSp node but same FQDN
*
* @throws Exception
*/
@Test
- public void validateUniqueIdDifferentHomeSp() throws Exception {
+ public void validateUniqueIdDifferentHomeSpSameFqdn() throws Exception {
PasspointConfiguration config1 = PasspointTestUtils.createConfig();
- // Modify config2's RCOIs to a different set of values
+ // Modify config2's RCOIs and friendly name to a different set of values
PasspointConfiguration config2 = PasspointTestUtils.createConfig();
HomeSp homeSp = config2.getHomeSp();
homeSp.setRoamingConsortiumOis(new long[] {0xaa, 0xbb});
+ homeSp.setFriendlyName("Some other name");
+ config2.setHomeSp(homeSp);
+
+ assertEquals(config1.getUniqueId(), config2.getUniqueId());
+ }
+
+ /**
+ * Verify that the unique identifier generated is different for two instances with the same
+ * HomeSp node but different FQDN
+ *
+ * @throws Exception
+ */
+ @Test
+ public void validateUniqueIdSameHomeSpDifferentFqdn() throws Exception {
+ PasspointConfiguration config1 = PasspointTestUtils.createConfig();
+
+ // Modify config2's FQDN to a different value
+ PasspointConfiguration config2 = PasspointTestUtils.createConfig();
+ HomeSp homeSp = config2.getHomeSp();
+ homeSp.setFqdn("fqdn2.com");
config2.setHomeSp(homeSp);
assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
@@ -403,15 +430,15 @@ public class PasspointConfigurationTest {
/**
* Verify that the unique identifier generated is different for two instances with different
- * Credential node
+ * SIM Credential node
*
* @throws Exception
*/
@Test
- public void validateUniqueIdDifferentCredential() throws Exception {
+ public void validateUniqueIdDifferentSimCredential() throws Exception {
PasspointConfiguration config1 = PasspointTestUtils.createConfig();
- // Modify config2's RCOIs to a different set of values
+ // Modify config2's realm and SIM credential to a different set of values
PasspointConfiguration config2 = PasspointTestUtils.createConfig();
Credential credential = config2.getCredential();
credential.setRealm("realm2.example.com");
@@ -422,6 +449,157 @@ public class PasspointConfigurationTest {
}
/**
+ * Verify that the unique identifier generated is different for two instances with different
+ * Realm in the Credential node
+ *
+ * @throws Exception
+ */
+ @Test
+ public void validateUniqueIdDifferentRealm() throws Exception {
+ PasspointConfiguration config1 = PasspointTestUtils.createConfig();
+
+ // Modify config2's realm to a different set of values
+ PasspointConfiguration config2 = PasspointTestUtils.createConfig();
+ Credential credential = config2.getCredential();
+ credential.setRealm("realm2.example.com");
+ config2.setCredential(credential);
+
+ assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
+ }
+
+ /**
+ * Verify that the unique identifier generated is the same for two instances with different
+ * password and same username in the User Credential node
+ *
+ * @throws Exception
+ */
+ @Test
+ public void validateUniqueIdSameUserInUserCredential() throws Exception {
+ PasspointConfiguration config1 = PasspointTestUtils.createConfig();
+ Credential credential = createCredentialWithUserCredential("user", "passwd");
+ config1.setCredential(credential);
+
+ // Modify config2's Passpowrd to a different set of values
+ PasspointConfiguration config2 = PasspointTestUtils.createConfig();
+ credential = createCredentialWithUserCredential("user", "newpasswd");
+ config2.setCredential(credential);
+
+ assertEquals(config1.getUniqueId(), config2.getUniqueId());
+ }
+
+ /**
+ * Verify that the unique identifier generated is different for two instances with different
+ * username in the User Credential node
+ *
+ * @throws Exception
+ */
+ @Test
+ public void validateUniqueIdDifferentUserCredential() throws Exception {
+ PasspointConfiguration config1 = PasspointTestUtils.createConfig();
+ Credential credential = createCredentialWithUserCredential("user", "passwd");
+ config1.setCredential(credential);
+
+ // Modify config2's username to a different value
+ PasspointConfiguration config2 = PasspointTestUtils.createConfig();
+ credential = createCredentialWithUserCredential("user2", "passwd");
+ config2.setCredential(credential);
+
+ assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
+ }
+
+ /**
+ * Verify that the unique identifier generated is different for two instances with different
+ * Cert Credential node
+ *
+ * @throws Exception
+ */
+ @Test
+ public void validateUniqueIdDifferentCertCredential() throws Exception {
+ PasspointConfiguration config1 = PasspointTestUtils.createConfig();
+ Credential credential = createCredentialWithCertificateCredential(true, true);
+ config1.setCredential(credential);
+
+ // Modify config2's cert credential to a different set of values
+ PasspointConfiguration config2 = PasspointTestUtils.createConfig();
+ credential = createCredentialWithCertificateCredential(false, false);
+ config2.setCredential(credential);
+
+ assertNotEquals(config1.getUniqueId(), config2.getUniqueId());
+ }
+
+ /**
+ * Helper function for generating certificate credential for testing.
+ *
+ * @return {@link Credential}
+ */
+ private static Credential createCredentialWithCertificateCredential(Boolean useCaCert0,
+ Boolean useCert0)
+ throws NoSuchAlgorithmException, CertificateEncodingException {
+ Credential.CertificateCredential certCred = new Credential.CertificateCredential();
+ certCred.setCertType("x509v3");
+ if (useCert0) {
+ certCred.setCertSha256Fingerprint(
+ MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
+ } else {
+ certCred.setCertSha256Fingerprint(MessageDigest.getInstance("SHA-256")
+ .digest(FakeKeys.CLIENT_SUITE_B_RSA3072_CERT.getEncoded()));
+ }
+ return createCredential(null, certCred, null, new X509Certificate[] {FakeKeys.CLIENT_CERT},
+ FakeKeys.RSA_KEY1, useCaCert0 ? FakeKeys.CA_CERT0 : FakeKeys.CA_CERT1);
+ }
+
+ /**
+ * Helper function for generating user credential for testing.
+ *
+ * @return {@link Credential}
+ */
+ private static Credential createCredentialWithUserCredential(String username, String password) {
+ Credential.UserCredential userCred = new Credential.UserCredential();
+ userCred.setUsername(username);
+ userCred.setPassword(password);
+ userCred.setMachineManaged(true);
+ userCred.setAbleToShare(true);
+ userCred.setSoftTokenApp("TestApp");
+ userCred.setEapType(EAPConstants.EAP_TTLS);
+ userCred.setNonEapInnerMethod("MS-CHAP");
+ return createCredential(userCred, null, null, null, null, FakeKeys.CA_CERT0);
+ }
+
+ /**
+ * Helper function for generating Credential for testing.
+ *
+ * @param userCred Instance of UserCredential
+ * @param certCred Instance of CertificateCredential
+ * @param simCred Instance of SimCredential
+ * @param clientCertificateChain Chain of client certificates
+ * @param clientPrivateKey Client private key
+ * @param caCerts CA certificates
+ * @return {@link Credential}
+ */
+ private static Credential createCredential(Credential.UserCredential userCred,
+ Credential.CertificateCredential certCred,
+ Credential.SimCredential simCred,
+ X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey,
+ X509Certificate... caCerts) {
+ Credential cred = new Credential();
+ cred.setCreationTimeInMillis(123455L);
+ cred.setExpirationTimeInMillis(2310093L);
+ cred.setRealm("realm");
+ cred.setCheckAaaServerCertStatus(true);
+ cred.setUserCredential(userCred);
+ cred.setCertCredential(certCred);
+ cred.setSimCredential(simCred);
+ if (caCerts != null && caCerts.length == 1) {
+ cred.setCaCertificate(caCerts[0]);
+ } else {
+ cred.setCaCertificates(caCerts);
+ }
+ cred.setClientCertificateChain(clientCertificateChain);
+ cred.setClientPrivateKey(clientPrivateKey);
+ return cred;
+ }
+
+ /**
* Verify that the unique identifier API generates an exception if HomeSP is not initialized.
*
* @throws Exception
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
index 829d8f0a9a3a..a44df40a8e97 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
@@ -593,10 +593,10 @@ public class CredentialTest {
}
/**
- * Verify that unique identifiers are different for a credential with different values
+ * Verify that unique identifiers are different for a credential with different username
*/
@Test
- public void testUniqueIdDifferentForUserCredentialsWithDifferentValues() throws Exception {
+ public void testUniqueIdDifferentForUserCredentialsWithDifferentUsername() throws Exception {
Credential userCred1 = createCredentialWithUserCredential();
Credential userCred2 = createCredentialWithUserCredential();
userCred2.getUserCredential().setUsername("anotheruser");
@@ -605,7 +605,24 @@ public class CredentialTest {
}
/**
- * Verify that unique identifiers are different for a credential with different values
+ * Verify that unique identifiers are different for a credential with different password and
+ * other values other than username
+ */
+ @Test
+ public void testUniqueIdSameForUserCredentialsWithDifferentPassword() throws Exception {
+ Credential userCred1 = createCredentialWithUserCredential();
+ Credential userCred2 = createCredentialWithUserCredential();
+ userCred2.getUserCredential().setPassword("someotherpassword!");
+ userCred2.getUserCredential().setMachineManaged(false);
+ userCred2.getUserCredential().setAbleToShare(false);
+ userCred2.getUserCredential().setSoftTokenApp("TestApp2");
+ userCred2.getUserCredential().setNonEapInnerMethod("PAP");
+
+ assertEquals(userCred1.getUniqueId(), userCred2.getUniqueId());
+ }
+
+ /**
+ * Verify that unique identifiers are different for a cert credential with different values
*/
@Test
public void testUniqueIdDifferentForCertCredentialsWithDifferentValues() throws Exception {