summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt26
-rw-r--r--core/api/system-current.txt2
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.aidl23
-rw-r--r--core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java113
-rw-r--r--core/java/android/app/appfunctions/ExecuteAppFunctionResponse.aidl21
-rw-r--r--core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java294
-rw-r--r--core/java/android/companion/virtual/VirtualDeviceManager.java1
-rw-r--r--core/java/android/companion/virtual/flags.aconfig15
-rw-r--r--core/java/android/hardware/input/input_framework.aconfig7
-rw-r--r--core/java/android/os/UserManager.java4
-rw-r--r--core/java/android/permission/flags.aconfig7
-rw-r--r--core/java/android/provider/Settings.java1
-rw-r--r--core/java/android/service/dreams/DreamService.java3
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java3
-rw-r--r--core/java/android/view/HandwritingInitiator.java5
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/java/android/view/ViewOverlay.java15
-rw-r--r--core/java/android/view/ViewRootImpl.java2
-rw-r--r--core/java/android/view/inputmethod/InputConnection.java5
-rw-r--r--core/java/android/view/inputmethod/InputMethodInfo.java9
-rw-r--r--core/java/com/android/internal/pm/pkg/component/ParsedProviderImpl.java6
-rw-r--r--core/java/com/android/internal/policy/PhoneWindow.java1
-rw-r--r--core/java/com/android/internal/protolog/LegacyProtoLogImpl.java1
-rw-r--r--core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java5
-rw-r--r--core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java45
-rw-r--r--core/java/com/android/internal/protolog/ProtoLog.java36
-rw-r--r--core/java/com/android/internal/protolog/ProtoLogImpl.java23
-rw-r--r--core/java/com/android/internal/protolog/common/IProtoLog.java6
-rw-r--r--core/jni/android_os_SELinux.cpp14
-rw-r--r--core/res/Android.bp2
-rw-r--r--core/res/AndroidManifest.xml38
-rw-r--r--core/res/res/drawable/ic_zen_mode_icon_lotus_flower.xml25
-rw-r--r--core/res/res/drawable/ic_zen_mode_icon_rabbit.xml25
-rw-r--r--core/res/res/drawable/ic_zen_mode_type_unknown.xml2
-rw-r--r--core/res/res/layout/input_method_switch_dialog_new.xml3
-rw-r--r--core/res/res/values/strings.xml6
-rw-r--r--core/res/res/values/themes_device_defaults.xml1706
-rw-r--r--core/tests/coretests/src/android/view/ViewFrameRateTest.java29
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/BackupHelper.java101
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java21
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java15
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java56
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java2
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java2
-rw-r--r--libs/WindowManager/Shell/res/layout/compat_ui_restart_button_layout.xml41
-rw-r--r--libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponent.kt212
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentFactory.kt30
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentState.kt5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt31
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/components/RestartButtonSpec.kt58
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIComponentFactory.kt51
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt46
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeDragAndDropTransitionHandler.kt111
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java82
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt113
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java38
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java6
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindow.kt87
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIComponentTest.kt122
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIHandlerRule.kt67
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIStateUtil.kt1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandlerTest.kt132
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt18
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIComponentFactory.kt69
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILayout.kt111
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILifecyclePredicates.kt4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUISpec.kt7
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt68
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt45
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java32
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt170
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt5
-rw-r--r--libs/androidfw/AssetManager2.cpp12
-rw-r--r--libs/androidfw/include/androidfw/AssetManager2.h12
-rw-r--r--libs/androidfw/tests/AssetManager2_test.cpp20
-rw-r--r--libs/androidfw/tests/BenchmarkHelpers.cpp2
-rw-r--r--libs/androidfw/tests/Theme_test.cpp2
-rw-r--r--nfc/java/android/nfc/cardemulation/CardEmulation.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java29
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java6
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java33
-rw-r--r--packages/SettingsProvider/Android.bp1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java122
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig11
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt2
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt40
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt13
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt16
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt45
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt107
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt17
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt58
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt12
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractor.kt91
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogLogger.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogRepository.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt96
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt20
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt32
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/NewPickerUiKeyguardPreview.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt42
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt57
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/OWNERS10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt36
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorKosmos.kt37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt226
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt31
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/TutorialSchedulerRepositoryTest.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt64
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt2
-rw-r--r--ravenwood/tools/ravenizer-fake/Android.bp14
-rwxr-xr-xravenwood/tools/ravenizer-fake/ravenizer31
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java562
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java18
-rw-r--r--services/core/java/com/android/server/PackageWatchdog.java27
-rw-r--r--services/core/java/com/android/server/RescueParty.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java39
-rw-r--r--services/core/java/com/android/server/am/BroadcastRecord.java41
-rw-r--r--services/core/java/com/android/server/am/BroadcastSentEventRecord.java134
-rw-r--r--services/core/java/com/android/server/am/flags.aconfig11
-rw-r--r--services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java8
-rw-r--r--services/core/java/com/android/server/biometrics/log/BiometricLogger.java9
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java5
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java8
-rw-r--r--services/core/java/com/android/server/display/notifications/DisplayNotificationManager.java8
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java186
-rw-r--r--services/core/java/com/android/server/notification/GroupHelper.java32
-rw-r--r--services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java2
-rw-r--r--services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java50
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorManagerService.java41
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java66
-rw-r--r--services/core/java/com/android/server/wm/BackNavigationController.java4
-rw-r--r--services/core/java/com/android/server/wm/DimmerAnimationHelper.java54
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java5
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java29
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java37
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java8
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java39
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/notifications/DisplayNotificationManagerTest.java13
-rw-r--r--services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java36
-rw-r--r--services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClientTest.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java27
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java110
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java22
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java4
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteSubscriberInfo.java2
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteSubscriberProvisionStatus.java2
-rw-r--r--tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java5
-rw-r--r--tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java2
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt17
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt12
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt19
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt2
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt41
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt33
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt47
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt59
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt (renamed from tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapper.kt)31
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt114
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt296
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt301
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt332
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt301
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt452
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt22
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.java36
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.java58
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java26
-rw-r--r--tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt2
224 files changed, 7910 insertions, 2453 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index c42d1ffcba6d..66a1d308eb7b 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -26,6 +26,7 @@ package android {
field public static final String BATTERY_STATS = "android.permission.BATTERY_STATS";
field public static final String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
field public static final String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
+ field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final String BIND_APP_FUNCTION_SERVICE = "android.permission.BIND_APP_FUNCTION_SERVICE";
field public static final String BIND_AUTOFILL_SERVICE = "android.permission.BIND_AUTOFILL_SERVICE";
field public static final String BIND_CALL_REDIRECTION_SERVICE = "android.permission.BIND_CALL_REDIRECTION_SERVICE";
field public static final String BIND_CARRIER_MESSAGING_CLIENT_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE";
@@ -8740,6 +8741,31 @@ package android.app.appfunctions {
method @NonNull public android.app.appfunctions.ExecuteAppFunctionRequest.Builder setParameters(@NonNull android.app.appsearch.GenericDocument);
}
+ @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public final class ExecuteAppFunctionResponse implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public String getErrorMessage();
+ method @NonNull public android.os.Bundle getExtras();
+ method public int getResultCode();
+ method @NonNull public android.app.appsearch.GenericDocument getResultDocument();
+ method public boolean isSuccess();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.appfunctions.ExecuteAppFunctionResponse> CREATOR;
+ field public static final String PROPERTY_RETURN_VALUE = "returnValue";
+ field public static final int RESULT_APP_UNKNOWN_ERROR = 2; // 0x2
+ field public static final int RESULT_DENIED = 1; // 0x1
+ field public static final int RESULT_INTERNAL_ERROR = 3; // 0x3
+ field public static final int RESULT_INVALID_ARGUMENT = 4; // 0x4
+ field public static final int RESULT_OK = 0; // 0x0
+ field public static final int RESULT_TIMED_OUT = 5; // 0x5
+ }
+
+ @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final class ExecuteAppFunctionResponse.Builder {
+ ctor public ExecuteAppFunctionResponse.Builder(@NonNull android.app.appsearch.GenericDocument);
+ ctor public ExecuteAppFunctionResponse.Builder(int, @NonNull String);
+ method @NonNull public android.app.appfunctions.ExecuteAppFunctionResponse build();
+ method @NonNull public android.app.appfunctions.ExecuteAppFunctionResponse.Builder setExtras(@NonNull android.os.Bundle);
+ }
+
}
package android.app.assist {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 445a57220757..fe792bc3a10b 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -139,6 +139,8 @@ package android {
field @FlaggedApi("com.android.window.flags.untrusted_embedding_any_app_permission") public static final String EMBED_ANY_APP_IN_UNTRUSTED_MODE = "android.permission.EMBED_ANY_APP_IN_UNTRUSTED_MODE";
field @FlaggedApi("android.content.pm.emergency_install_permission") public static final String EMERGENCY_INSTALL_PACKAGES = "android.permission.EMERGENCY_INSTALL_PACKAGES";
field public static final String ENTER_CAR_MODE_PRIORITIZED = "android.permission.ENTER_CAR_MODE_PRIORITIZED";
+ field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final String EXECUTE_APP_FUNCTIONS = "android.permission.EXECUTE_APP_FUNCTIONS";
+ field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final String EXECUTE_APP_FUNCTIONS_TRUSTED = "android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED";
field public static final String EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS = "android.permission.EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS";
field public static final String FORCE_BACK = "android.permission.FORCE_BACK";
field public static final String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 0db91f5667ee..177b859da0ad 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -941,7 +941,7 @@ package android.companion.virtual {
method public int getAudioRecordingSessionId(int);
method public int getDeviceIdForDisplayId(int);
method public int getDevicePolicy(int, int);
- method @FlaggedApi("android.companion.virtual.flags.interactive_screen_mirror") public boolean isVirtualDeviceOwnedMirrorDisplay(int);
+ method public boolean isVirtualDeviceOwnedMirrorDisplay(int);
method public void playSoundEffect(int, int);
}
diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.aidl b/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.aidl
new file mode 100644
index 000000000000..42ec45df8f25
--- /dev/null
+++ b/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.aidl
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package android.app.appfunctions;
+
+import android.app.appfunctions.ExecuteAppFunctionAidlRequest;
+
+/** {@hide} */
+parcelable ExecuteAppFunctionAidlRequest; \ No newline at end of file
diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java b/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java
new file mode 100644
index 000000000000..2f3c555d9465
--- /dev/null
+++ b/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app.appfunctions;
+
+import static android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+
+
+import java.util.Objects;
+
+/**
+ * An internal request to execute an app function.
+ *
+ * @hide
+ */
+@FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER)
+public final class ExecuteAppFunctionAidlRequest implements Parcelable {
+
+ public static final Creator<ExecuteAppFunctionAidlRequest> CREATOR =
+ new Creator<ExecuteAppFunctionAidlRequest>() {
+ @Override
+ public ExecuteAppFunctionAidlRequest createFromParcel(Parcel in) {
+ ExecuteAppFunctionRequest clientRequest =
+ ExecuteAppFunctionRequest.CREATOR.createFromParcel(in);
+ UserHandle userHandle =
+ UserHandle.CREATOR.createFromParcel(in);
+ String callingPackage = in.readString8();
+ return new ExecuteAppFunctionAidlRequest(
+ clientRequest, userHandle, callingPackage);
+ }
+
+ @Override
+ public ExecuteAppFunctionAidlRequest[] newArray(int size) {
+ return new ExecuteAppFunctionAidlRequest[size];
+ }
+ };
+
+ /**
+ * The client request to execute an app function.
+ */
+ private final ExecuteAppFunctionRequest mClientRequest;
+
+ /**
+ * The user handle of the user to execute the app function.
+ */
+ private final UserHandle mUserHandle;
+
+ /**
+ * The package name of the app that is requesting to execute the app function.
+ */
+ private final String mCallingPackage;
+
+ public ExecuteAppFunctionAidlRequest(
+ ExecuteAppFunctionRequest clientRequest, UserHandle userHandle, String callingPackage) {
+ this.mClientRequest = Objects.requireNonNull(clientRequest);
+ this.mUserHandle = Objects.requireNonNull(userHandle);
+ this.mCallingPackage = Objects.requireNonNull(callingPackage);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ mClientRequest.writeToParcel(dest, flags);
+ mUserHandle.writeToParcel(dest, flags);
+ dest.writeString8(mCallingPackage);
+ }
+
+ /**
+ * Returns the client request to execute an app function.
+ */
+ @NonNull
+ public ExecuteAppFunctionRequest getClientRequest() {
+ return mClientRequest;
+ }
+
+ /**
+ * Returns the user handle of the user to execute the app function.
+ */
+ @NonNull
+ public UserHandle getUserHandle() {
+ return mUserHandle;
+ }
+
+ /**
+ * Returns the package name of the app that is requesting to execute the app function.
+ */
+ @NonNull
+ public String getCallingPackage() {
+ return mCallingPackage;
+ }
+}
diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.aidl b/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.aidl
new file mode 100644
index 000000000000..5194e7a4c73f
--- /dev/null
+++ b/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package android.app.appfunctions;
+
+import android.app.appfunctions.ExecuteAppFunctionResponse;
+
+parcelable ExecuteAppFunctionResponse; \ No newline at end of file
diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java b/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java
new file mode 100644
index 000000000000..72205d9cf6c6
--- /dev/null
+++ b/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.appfunctions;
+
+import static android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.appsearch.GenericDocument;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * The response to an app function execution.
+ */
+@FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER)
+public final class ExecuteAppFunctionResponse implements Parcelable {
+ @NonNull
+ public static final Creator<ExecuteAppFunctionResponse> CREATOR =
+ new Creator<ExecuteAppFunctionResponse>() {
+ @Override
+ public ExecuteAppFunctionResponse createFromParcel(Parcel parcel) {
+ GenericDocument result =
+ Objects.requireNonNull(GenericDocument.createFromParcel(parcel));
+ Bundle extras = Objects.requireNonNull(
+ parcel.readBundle(Bundle.class.getClassLoader()));
+ int resultCode = parcel.readInt();
+ String errorMessage = parcel.readString8();
+ return new ExecuteAppFunctionResponse(result, extras, resultCode, errorMessage);
+ }
+
+ @Override
+ public ExecuteAppFunctionResponse[] newArray(int size) {
+ return new ExecuteAppFunctionResponse[size];
+ }
+ };
+ /**
+ * The name of the property that stores the function return value within the
+ * {@code resultDocument}.
+ *
+ * <p>See {@link GenericDocument#getProperty(String)} for more information.
+ *
+ * <p>If the function returns {@code void} or throws an error, the {@code resultDocument}
+ * will be empty {@link GenericDocument}.
+ *
+ * <p>If the {@code resultDocument} is empty, {@link GenericDocument#getProperty(String)} will
+ * return {@code null}.
+ *
+ * <p>See {@link #getResultDocument} for more information on extracting the return value.
+ */
+ public static final String PROPERTY_RETURN_VALUE = "returnValue";
+
+ /**
+ * The call was successful.
+ */
+ public static final int RESULT_OK = 0;
+
+ /**
+ * The caller does not have the permission to execute an app function.
+ */
+ public static final int RESULT_DENIED = 1;
+
+ /**
+ * An unknown error occurred while processing the call in the AppFunctionService.
+ */
+ public static final int RESULT_APP_UNKNOWN_ERROR = 2;
+
+ /**
+ * An internal error occurred within AppFunctionManagerService.
+ *
+ * <p>This error may be considered similar to {@link IllegalStateException}
+ */
+ public static final int RESULT_INTERNAL_ERROR = 3;
+
+ /**
+ * The caller supplied invalid arguments to the call.
+ *
+ * <p>This error may be considered similar to {@link IllegalArgumentException}.
+ */
+ public static final int RESULT_INVALID_ARGUMENT = 4;
+
+ /**
+ * The operation was timed out.
+ */
+ public static final int RESULT_TIMED_OUT = 5;
+
+ /**
+ * The result code of the app function execution.
+ */
+ @ResultCode
+ private final int mResultCode;
+
+ /**
+ * The error message associated with the result, if any. This is {@code null} if the result code
+ * is {@link #RESULT_OK}.
+ */
+ @Nullable
+ private final String mErrorMessage;
+
+ /**
+ * Returns the return value of the executed function.
+ *
+ * <p>The return value is stored in a {@link GenericDocument} with the key
+ * {@link #PROPERTY_RETURN_VALUE}.
+ *
+ * <p>See {@link #getResultDocument} for more information on extracting the return value.
+ */
+ @NonNull
+ private final GenericDocument mResultDocument;
+
+ /**
+ * Returns the additional metadata data relevant to this function execution response.
+ */
+ @NonNull
+ private final Bundle mExtras;
+
+ private ExecuteAppFunctionResponse(@NonNull GenericDocument resultDocument,
+ @NonNull Bundle extras,
+ @ResultCode int resultCode,
+ @Nullable String errorMessage) {
+ mResultDocument = Objects.requireNonNull(resultDocument);
+ mExtras = Objects.requireNonNull(extras);
+ mResultCode = resultCode;
+ mErrorMessage = errorMessage;
+ }
+
+ /**
+ * Returns a generic document containing the return value of the executed function.
+ *
+ * <p>The {@link #PROPERTY_RETURN_VALUE} key can be used to obtain the return value.</p>
+ *
+ * <p>An empty document is returned if {@link #isSuccess} is {@code false} or if the executed
+ * function does not produce a return value.
+ *
+ * <p>Sample code for extracting the return value:
+ * <pre>
+ * GenericDocument resultDocument = response.getResultDocument();
+ * Object returnValue = resultDocument.getProperty(PROPERTY_RETURN_VALUE);
+ * if (returnValue != null) {
+ * // Cast returnValue to expected type, or use {@link GenericDocument#getPropertyString},
+ * // {@link GenericDocument#getPropertyLong} etc.
+ * // Do something with the returnValue
+ * }
+ * </pre>
+ */
+ @NonNull
+ public GenericDocument getResultDocument() {
+ return mResultDocument;
+ }
+
+ /**
+ * Returns the extras of the app function execution.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ /**
+ * Returns {@code true} if {@link #getResultCode} equals
+ * {@link ExecuteAppFunctionResponse#RESULT_OK}.
+ */
+ public boolean isSuccess() {
+ return getResultCode() == RESULT_OK;
+ }
+
+ /**
+ * Returns one of the {@code RESULT} constants defined in {@link ExecuteAppFunctionResponse}.
+ */
+ @ResultCode
+ public int getResultCode() {
+ return mResultCode;
+ }
+
+ /**
+ * Returns the error message associated with this result.
+ *
+ * <p>If {@link #isSuccess} is {@code true}, the error message is always {@code null}.
+ */
+ @Nullable
+ public String getErrorMessage() {
+ return mErrorMessage;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ mResultDocument.writeToParcel(dest, flags);
+ dest.writeBundle(mExtras);
+ dest.writeInt(mResultCode);
+ dest.writeString8(mErrorMessage);
+ }
+
+ /**
+ * Result codes.
+ *
+ * @hide
+ */
+ @IntDef(
+ prefix = {"RESULT_"},
+ value = {
+ RESULT_OK,
+ RESULT_DENIED,
+ RESULT_APP_UNKNOWN_ERROR,
+ RESULT_INTERNAL_ERROR,
+ RESULT_INVALID_ARGUMENT,
+ RESULT_TIMED_OUT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ResultCode {
+ }
+
+ /**
+ * The builder for creating {@link ExecuteAppFunctionResponse} instances.
+ */
+ @FlaggedApi(FLAG_ENABLE_APP_FUNCTION_MANAGER)
+ public static final class Builder {
+ @NonNull
+ private GenericDocument mResultDocument = new GenericDocument.Builder<>("", "", "").build();
+ @NonNull
+ private Bundle mExtras = Bundle.EMPTY;
+ private int mResultCode;
+ @Nullable
+ private String mErrorMessage;
+
+ /**
+ * Creates a new builder for {@link ExecuteAppFunctionResponse}.
+ */
+ private Builder() {
+ }
+
+ /**
+ * Creates a new builder for {@link ExecuteAppFunctionResponse} to build a success response
+ * with a result code of {@link #RESULT_OK} and a resultDocument.
+ */
+ public Builder(@NonNull GenericDocument resultDocument) {
+ mResultDocument = Objects.requireNonNull(resultDocument);
+ mResultCode = RESULT_OK;
+ }
+
+ /**
+ * Creates a new builder for {@link ExecuteAppFunctionResponse} to build an error response
+ * with a result code and an error message.
+ */
+ public Builder(@ResultCode int resultCode,
+ @NonNull String errorMessage) {
+ mResultCode = resultCode;
+ mErrorMessage = Objects.requireNonNull(errorMessage);
+ }
+
+ /**
+ * Sets the extras of the app function execution.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = Objects.requireNonNull(extras);
+ return this;
+ }
+
+ /**
+ * Builds the {@link ExecuteAppFunctionResponse} instance.
+ */
+ @NonNull
+ public ExecuteAppFunctionResponse build() {
+ return new ExecuteAppFunctionResponse(
+ mResultDocument, mExtras, mResultCode, mErrorMessage);
+ }
+ }
+}
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 8b60580ec114..d07fb2508a49 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -531,7 +531,6 @@ public final class VirtualDeviceManager {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR)
@TestApi
public boolean isVirtualDeviceOwnedMirrorDisplay(int displayId) {
if (mService == null) {
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index 91586b6bfae2..fc9c94dd5b0f 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -35,13 +35,6 @@ flag {
}
flag {
- name: "consistent_display_flags"
- namespace: "virtual_devices"
- description: "Make virtual display flags consistent with display manager"
- bug: "300905478"
-}
-
-flag {
name: "vdm_custom_ime"
is_exported: true
namespace: "virtual_devices"
@@ -89,14 +82,6 @@ flag {
}
flag {
- name: "interactive_screen_mirror"
- is_exported: true
- namespace: "virtual_devices"
- description: "Enable interactive screen mirroring using Virtual Devices"
- bug: "292212199"
-}
-
-flag {
name: "virtual_stylus"
is_exported: true
namespace: "virtual_devices"
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index 6f1d63d856b4..83c4de31824d 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -92,3 +92,10 @@ flag {
description: "Dump keyboard shortcuts in dumpsys window"
bug: "351963350"
}
+
+flag {
+ name: "modifier_shortcut_manager_refactor"
+ namespace: "input"
+ description: "Refactor ModifierShortcutManager internal representation of shortcuts."
+ bug: "358603902"
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 28f2c2530ae9..536eca6f9a0f 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -969,9 +969,7 @@ public class UserManager {
/**
* Specifies if a user is disallowed from adding new users. This can only be set by device
- * owners or profile owners on the primary user. The default value is <code>false</code>.
- * <p>This restriction has no effect on secondary users and managed profiles since only the
- * primary user can add other users.
+ * owners or profile owners on the main user. The default value is <code>false</code>.
* <p> When the device is an organization-owned device provisioned with a managed profile,
* this restriction will be set as a base restriction which cannot be removed by any admin.
*
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 4c4aa6cc4e68..5174005a8175 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -217,6 +217,13 @@ flag {
}
flag {
+ name: "check_op_validate_package"
+ namespace: "permissions"
+ description: "Validate package/uid match in checkOp similar to noteOp"
+ bug: "294609684"
+}
+
+flag {
name: "location_bypass_privacy_dashboard_enabled"
is_exported: true
namespace: "permissions"
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7ca40ea23d57..184bac4269bb 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -14953,6 +14953,7 @@ public final class Settings {
*
* @hide
*/
+ @Readable
public static final String MUTE_ALARM_STREAM_WITH_RINGER_MODE =
"mute_alarm_stream_with_ringer_mode";
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 9c281f3d6f90..0242de0b972c 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -1363,6 +1363,9 @@ public class DreamService extends Service implements Window.Callback {
* Tells the dream to come to the front (which in turn tells the overlay to come to the front).
*/
private void comeToFront() {
+ if (mOverlayConnection == null) {
+ return;
+ }
mOverlayConnection.addConsumer(overlay -> {
try {
overlay.comeToFront();
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 08e51a131198..1734223ec4c1 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -1078,6 +1078,9 @@ public abstract class WallpaperService extends Service {
out.print(prefix); out.print("mDisplay="); out.println(mDisplay);
out.print(prefix); out.print("mCreated="); out.print(mCreated);
out.print(" mSurfaceCreated="); out.print(mSurfaceCreated);
+ if (noDuplicateSurfaceDestroyedEvents()) {
+ out.print(" mReportedSurfaceCreated="); out.print(mReportedSurfaceCreated);
+ }
out.print(" mIsCreating="); out.print(mIsCreating);
out.print(" mDrawingAllowed="); out.println(mDrawingAllowed);
out.print(prefix); out.print("mWidth="); out.print(mWidth);
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index ccec89bb6262..8912035c0be3 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -350,12 +350,13 @@ public class HandwritingInitiator {
return;
}
+ final View focusedView = getFocusedView();
+
if (!view.isAutoHandwritingEnabled()) {
- clearFocusedView(view);
+ clearFocusedView(focusedView);
return;
}
- final View focusedView = getFocusedView();
if (focusedView == view) {
return;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3088fd3094b0..e81f32e1e64b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -33989,7 +33989,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|| mLastFrameTop != mTop)
&& viewRootImpl.shouldCheckFrameRateCategory()
&& parent instanceof View
- && ((View) parent).mFrameContentVelocity <= 0
+ && ((View) parent).getFrameContentVelocity() <= 0
&& !isInputMethodWindowType) {
return FRAME_RATE_CATEGORY_HIGH_HINT | FRAME_RATE_CATEGORY_REASON_BOOST;
diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java
index 02f7e95ba742..2786c84521c5 100644
--- a/core/java/android/view/ViewOverlay.java
+++ b/core/java/android/view/ViewOverlay.java
@@ -15,7 +15,10 @@
*/
package android.view;
+import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
+
import android.animation.LayoutTransition;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -365,6 +368,18 @@ public class ViewOverlay {
}
return null;
}
+
+ /**
+ * @hide
+ */
+ @Override
+ @FlaggedApi(FLAG_VIEW_VELOCITY_API)
+ public float getFrameContentVelocity() {
+ if (mHostView != null) {
+ return mHostView.getFrameContentVelocity();
+ }
+ return super.getFrameContentVelocity();
+ }
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fc7efb77f064..0e0262715d2f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -13012,7 +13012,7 @@ public final class ViewRootImpl implements ViewParent,
private boolean shouldSetFrameRateCategory() {
// use toolkitSetFrameRate flag to gate the change
- return shouldEnableDvrr() && mSurface.isValid() && shouldEnableDvrr();
+ return shouldEnableDvrr() && mSurface.isValid();
}
private boolean shouldSetFrameRate() {
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 1840bcb358a0..4742f1ed8219 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -625,8 +625,7 @@ public interface InputConnection {
* the text you are providing so it is not possible to correctly
* specify locations there.
* @param textAttribute The extra information about the text.
- * @return true on success, false if the input connection is no longer
- *
+ * @return true on success, false if the input connection is no longer valid.
*/
default boolean setComposingText(@NonNull CharSequence text, int newCursorPosition,
@Nullable TextAttribute textAttribute) {
@@ -753,7 +752,7 @@ public interface InputConnection {
* you are providing so it is not possible to correctly specify
* locations there.
* @param textAttribute The extra information about the text.
- * @return true on success, false if the input connection is no longer
+ * @return true on success, false if the input connection is no longer valid.
*/
default boolean commitText(@NonNull CharSequence text, int newCursorPosition,
@Nullable TextAttribute textAttribute) {
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 0e66f7ac47b7..806a59334689 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -878,15 +878,18 @@ public final class InputMethodInfo implements Parcelable {
/**
* Returns {@link Intent} for IME language settings activity with
- * {@link Intent#getAction() Intent action} {@link #ACTION_IME_LANGUAGE_SETTINGS},
- * else <code>null</code> if
- * {@link android.R.styleable#InputMethod_languageSettingsActivity} is not defined.
+ * {@link Intent#getAction() Intent action} {@link #ACTION_IME_LANGUAGE_SETTINGS}. If
+ * {@link android.R.styleable#InputMethod_languageSettingsActivity} is not defined, tries to
+ * fall back to the IME general settings activity. If
+ * {@link android.R.styleable#InputMethod_settingsActivity} is also not defined,
+ * returns {code null}.
*
* <p>To launch IME language settings, use this method to get the {@link Intent} to launch
* the IME language settings activity.</p>
* <p>e.g.<pre><code>startActivity(createImeLanguageSettingsActivityIntent());</code></pre></p>
*
* @attr ref R.styleable#InputMethod_languageSettingsActivity
+ * @attr ref R.styleable#InputMethod_settingsActivity
*/
@FlaggedApi(android.view.inputmethod.Flags.FLAG_IME_SWITCHER_REVAMP_API)
@Nullable
diff --git a/core/java/com/android/internal/pm/pkg/component/ParsedProviderImpl.java b/core/java/com/android/internal/pm/pkg/component/ParsedProviderImpl.java
index 987fd4158418..ec5ff4c6946a 100644
--- a/core/java/com/android/internal/pm/pkg/component/ParsedProviderImpl.java
+++ b/core/java/com/android/internal/pm/pkg/component/ParsedProviderImpl.java
@@ -174,7 +174,7 @@ public class ParsedProviderImpl extends ParsedMainComponentImpl implements Parse
// CHECKSTYLE:OFF Generated code
//
// To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/services/core/java/com/android/server/pm/pkg/component/ParsedProviderImpl.java
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/com/android/internal/pm/pkg/component/ParsedProviderImpl.java
//
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
// Settings > Editor > Code Style > Formatter Control
@@ -298,9 +298,9 @@ public class ParsedProviderImpl extends ParsedMainComponentImpl implements Parse
}
@DataClass.Generated(
- time = 1642560323360L,
+ time = 1723882842941L,
codegenVersion = "1.0.23",
- sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/component/ParsedProviderImpl.java",
+ sourceFile = "frameworks/base/core/java/com/android/internal/pm/pkg/component/ParsedProviderImpl.java",
inputSignatures = "private @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String authority\nprivate boolean syncable\nprivate @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String readPermission\nprivate @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) java.lang.String writePermission\nprivate boolean grantUriPermissions\nprivate boolean forceUriPermissions\nprivate boolean multiProcess\nprivate int initOrder\nprivate @android.annotation.NonNull java.util.List<android.os.PatternMatcher> uriPermissionPatterns\nprivate @android.annotation.NonNull java.util.List<android.content.pm.PathPermission> pathPermissions\npublic static final @android.annotation.NonNull android.os.Parcelable.Creator<com.android.internal.pm.pkg.component.ParsedProviderImpl> CREATOR\npublic com.android.internal.pm.pkg.component.ParsedProviderImpl setReadPermission(java.lang.String)\npublic com.android.internal.pm.pkg.component.ParsedProviderImpl setWritePermission(java.lang.String)\npublic @android.annotation.NonNull com.android.internal.pm.pkg.component.ParsedProviderImpl addUriPermissionPattern(android.os.PatternMatcher)\npublic @android.annotation.NonNull com.android.internal.pm.pkg.component.ParsedProviderImpl addPathPermission(android.content.pm.PathPermission)\npublic java.lang.String toString()\npublic @java.lang.Override int describeContents()\npublic @java.lang.Override void writeToParcel(android.os.Parcel,int)\nclass ParsedProviderImpl extends com.android.internal.pm.pkg.component.ParsedMainComponentImpl implements [com.android.internal.pm.pkg.component.ParsedProvider, android.os.Parcelable]\n@com.android.internal.util.DataClass(genSetters=true, genGetters=true, genParcelable=false, genBuilder=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index ec004d07c781..0d0207ff7c0e 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -418,6 +418,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mElevation = preservedWindow.getElevation();
mLoadElevation = false;
mForceDecorInstall = true;
+ mDecorFitsSystemWindows = preservedWindow.decorFitsSystemWindows();
setSystemBarAppearance(preservedWindow.getSystemBarAppearance());
// If we're preserving window, carry over the app token from the preserved
// window, as we'll be skipping the addView in handleResumeActivity(), and
diff --git a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
index fcc302331dae..2feb3d50cf64 100644
--- a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
@@ -419,7 +419,6 @@ public class LegacyProtoLogImpl implements IProtoLog {
return group.isLogToLogcat() || (group.isLogToProto() && isProtoEnabled());
}
- @Override
public void registerGroups(IProtoLogGroup... protoLogGroups) {
for (IProtoLogGroup group : protoLogGroups) {
mLogGroups.put(group.name(), group);
diff --git a/core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java b/core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java
index ebdad6d52933..e8d5195d121d 100644
--- a/core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java
@@ -79,9 +79,4 @@ public class LogcatOnlyProtoLogImpl implements IProtoLog {
public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
return true;
}
-
- @Override
- public void registerGroups(IProtoLogGroup... protoLogGroups) {
- // Does nothing
- }
}
diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
index 79a5469956df..7d12d49325d8 100644
--- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
@@ -89,6 +89,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Stream;
/**
* A service for the ProtoLog logging system.
@@ -125,17 +126,18 @@ public class PerfettoProtoLogImpl extends IProtoLogClient.Stub implements IProto
private final Lock mBackgroundServiceLock = new ReentrantLock();
private ExecutorService mBackgroundLoggingService = Executors.newSingleThreadExecutor();
- public PerfettoProtoLogImpl() {
- this(null, null, null, () -> {});
+ public PerfettoProtoLogImpl(@NonNull IProtoLogGroup[] groups) {
+ this(null, null, null, () -> {}, groups);
}
- public PerfettoProtoLogImpl(@NonNull Runnable cacheUpdater) {
- this(null, null, null, cacheUpdater);
+ public PerfettoProtoLogImpl(@NonNull Runnable cacheUpdater, @NonNull IProtoLogGroup[] groups) {
+ this(null, null, null, cacheUpdater, groups);
}
public PerfettoProtoLogImpl(
@NonNull String viewerConfigFilePath,
- @NonNull Runnable cacheUpdater) {
+ @NonNull Runnable cacheUpdater,
+ @NonNull IProtoLogGroup[] groups) {
this(viewerConfigFilePath,
null,
new ProtoLogViewerConfigReader(() -> {
@@ -146,22 +148,24 @@ public class PerfettoProtoLogImpl extends IProtoLogClient.Stub implements IProto
"Failed to load viewer config file " + viewerConfigFilePath, e);
}
}),
- cacheUpdater);
+ cacheUpdater, groups);
}
@VisibleForTesting
public PerfettoProtoLogImpl(
@Nullable ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
@Nullable ProtoLogViewerConfigReader viewerConfigReader,
- @NonNull Runnable cacheUpdater) {
- this(null, viewerConfigInputStreamProvider, viewerConfigReader, cacheUpdater);
+ @NonNull Runnable cacheUpdater,
+ @NonNull IProtoLogGroup[] groups) {
+ this(null, viewerConfigInputStreamProvider, viewerConfigReader, cacheUpdater, groups);
}
private PerfettoProtoLogImpl(
@Nullable String viewerConfigFilePath,
@Nullable ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
@Nullable ProtoLogViewerConfigReader viewerConfigReader,
- @NonNull Runnable cacheUpdater) {
+ @NonNull Runnable cacheUpdater,
+ @NonNull IProtoLogGroup[] groups) {
if (viewerConfigFilePath != null && viewerConfigInputStreamProvider != null) {
throw new RuntimeException("Only one of viewerConfigFilePath and "
+ "viewerConfigInputStreamProvider can be set");
@@ -179,6 +183,8 @@ public class PerfettoProtoLogImpl extends IProtoLogClient.Stub implements IProto
this.mViewerConfigReader = viewerConfigReader;
this.mCacheUpdater = cacheUpdater;
+ registerGroupsLocally(groups);
+
if (android.tracing.Flags.clientSideProtoLogging()) {
mProtoLogService =
IProtoLogService.Stub.asInterface(ServiceManager.getService(PROTOLOG_SERVICE));
@@ -192,6 +198,12 @@ public class PerfettoProtoLogImpl extends IProtoLogClient.Stub implements IProto
args.setViewerConfigFile(viewerConfigFilePath);
}
+ final var groupArgs = Stream.of(groups)
+ .map(group -> new ProtoLogService.RegisterClientArgs.GroupConfig(
+ group.name(), group.isLogToLogcat()))
+ .toArray(ProtoLogService.RegisterClientArgs.GroupConfig[]::new);
+ args.setGroups(groupArgs);
+
mProtoLogService.registerClient(this, args);
} catch (RemoteException e) {
throw new RuntimeException("Failed to register ProtoLog client");
@@ -294,19 +306,18 @@ public class PerfettoProtoLogImpl extends IProtoLogClient.Stub implements IProto
|| group.isLogToLogcat();
}
- @Override
- public void registerGroups(IProtoLogGroup... protoLogGroups) {
+ private void registerGroupsLocally(@NonNull IProtoLogGroup[] protoLogGroups) {
+ final var groupsLoggingToLogcat = new ArrayList<String>();
for (IProtoLogGroup protoLogGroup : protoLogGroups) {
mLogGroups.put(protoLogGroup.name(), protoLogGroup);
- }
- final String[] groupsLoggingToLogcat = Arrays.stream(protoLogGroups)
- .filter(IProtoLogGroup::isLogToLogcat)
- .map(IProtoLogGroup::name)
- .toArray(String[]::new);
+ if (protoLogGroup.isLogToLogcat()) {
+ groupsLoggingToLogcat.add(protoLogGroup.name());
+ }
+ }
if (mViewerConfigReader != null) {
- mViewerConfigReader.loadViewerConfig(groupsLoggingToLogcat);
+ mViewerConfigReader.loadViewerConfig(groupsLoggingToLogcat.toArray(new String[0]));
}
}
diff --git a/core/java/com/android/internal/protolog/ProtoLog.java b/core/java/com/android/internal/protolog/ProtoLog.java
index 87678e5922f9..f9b989477907 100644
--- a/core/java/com/android/internal/protolog/ProtoLog.java
+++ b/core/java/com/android/internal/protolog/ProtoLog.java
@@ -50,6 +50,24 @@ public class ProtoLog {
private static IProtoLog sProtoLogInstance;
/**
+ * Initialize ProtoLog in this process.
+ * <p>
+ * This method MUST be called before any protologging is performed in this process.
+ * Ensure that all groups that will be used for protologging are registered.
+ *
+ * @param groups The ProtoLog groups that will be used in the process.
+ */
+ public static void init(IProtoLogGroup... groups) {
+ if (android.tracing.Flags.perfettoProtologTracing()) {
+ sProtoLogInstance = new PerfettoProtoLogImpl(groups);
+ } else {
+ // The first call to ProtoLog is likely to flip REQUIRE_PROTOLOGTOOL, which is when this
+ // static block will be executed before REQUIRE_PROTOLOGTOOL is actually set.
+ sProtoLogInstance = new LogcatOnlyProtoLogImpl();
+ }
+ }
+
+ /**
* DEBUG level log.
*
* @param group {@code IProtoLogGroup} controlling this log call.
@@ -150,14 +168,6 @@ public class ProtoLog {
return sProtoLogInstance;
}
- /**
- * Registers available protolog groups. A group must be registered before it can be used.
- * @param protoLogGroups The groups to register for use in protolog.
- */
- public static void registerGroups(IProtoLogGroup... protoLogGroups) {
- sProtoLogInstance.registerGroups(protoLogGroups);
- }
-
private static void logStringMessage(LogLevel logLevel, IProtoLogGroup group,
String stringMessage, Object... args) {
if (sProtoLogInstance == null) {
@@ -169,14 +179,4 @@ public class ProtoLog {
sProtoLogInstance.log(logLevel, group, stringMessage, args);
}
}
-
- static {
- if (android.tracing.Flags.perfettoProtologTracing()) {
- sProtoLogInstance = new PerfettoProtoLogImpl();
- } else {
- // The first call to ProtoLog is likely to flip REQUIRE_PROTOLOGTOOL, which is when this
- // static block will be executed before REQUIRE_PROTOLOGTOOL is actually set.
- sProtoLogInstance = new LogcatOnlyProtoLogImpl();
- }
- }
}
diff --git a/core/java/com/android/internal/protolog/ProtoLogImpl.java b/core/java/com/android/internal/protolog/ProtoLogImpl.java
index 8659a8ffeb97..da6d8cff6890 100644
--- a/core/java/com/android/internal/protolog/ProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogImpl.java
@@ -93,35 +93,30 @@ public class ProtoLogImpl {
}
/**
- * Registers available protolog groups. A group must be registered before it can be used.
- * @param protoLogGroups The groups to register for use in protolog.
- */
- public static void registerGroups(IProtoLogGroup... protoLogGroups) {
- getSingleInstance().registerGroups(protoLogGroups);
- }
-
- /**
* Returns the single instance of the ProtoLogImpl singleton class.
*/
public static synchronized IProtoLog getSingleInstance() {
if (sServiceInstance == null) {
+ final var groups = sLogGroups.values().toArray(new IProtoLogGroup[0]);
+
if (android.tracing.Flags.perfettoProtologTracing()) {
File f = new File(sViewerConfigPath);
if (!ProtoLog.REQUIRE_PROTOLOGTOOL && !f.exists()) {
// TODO(b/353530422): Remove - temporary fix to unblock b/352290057
- // In so tests the viewer config file might not exist in which we don't
+ // In some tests the viewer config file might not exist in which we don't
// want to provide config path to the user
- sServiceInstance = new PerfettoProtoLogImpl(sCacheUpdater);
+ sServiceInstance = new PerfettoProtoLogImpl(sCacheUpdater, groups);
} else {
- sServiceInstance = new PerfettoProtoLogImpl(sViewerConfigPath, sCacheUpdater);
+ sServiceInstance =
+ new PerfettoProtoLogImpl(sViewerConfigPath, sCacheUpdater, groups);
}
} else {
- sServiceInstance = new LegacyProtoLogImpl(
+ var protologImpl = new LegacyProtoLogImpl(
sLegacyOutputFilePath, sLegacyViewerConfigPath, sCacheUpdater);
+ protologImpl.registerGroups(groups);
+ sServiceInstance = protologImpl;
}
- IProtoLogGroup[] groups = sLogGroups.values().toArray(new IProtoLogGroup[0]);
- sServiceInstance.registerGroups(groups);
sCacheUpdater.run();
}
return sServiceInstance;
diff --git a/core/java/com/android/internal/protolog/common/IProtoLog.java b/core/java/com/android/internal/protolog/common/IProtoLog.java
index f5695acd0614..d5c2ac10852f 100644
--- a/core/java/com/android/internal/protolog/common/IProtoLog.java
+++ b/core/java/com/android/internal/protolog/common/IProtoLog.java
@@ -68,10 +68,4 @@ public interface IProtoLog {
* @return If we need to log this group and level to either ProtoLog or Logcat.
*/
boolean isEnabled(IProtoLogGroup group, LogLevel level);
-
- /**
- * Registers available protolog groups. A group must be registered before it can be used.
- * @param protoLogGroups The groups to register for use in protolog.
- */
- void registerGroups(IProtoLogGroup... protoLogGroups);
}
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index 84ca1ba6ad7c..7a4670f4e49d 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -53,7 +53,7 @@ selabel_handle* GetSELabelHandle() {
}
struct SecurityContext_Delete {
- void operator()(security_context_t p) const {
+ void operator()(char* p) const {
freecon(p);
}
};
@@ -111,7 +111,7 @@ static jstring fileSelabelLookup(JNIEnv* env, jobject, jstring pathStr) {
return NULL;
}
- security_context_t tmp = NULL;
+ char* tmp = NULL;
if (selabel_lookup(selabel_handle, &tmp, path_c_str, S_IFREG) != 0) {
ALOGE("fileSelabelLookup => selabel_lookup for %s failed: %d", path_c_str, errno);
return NULL;
@@ -138,7 +138,7 @@ static jstring getFdConInner(JNIEnv *env, jobject fileDescriptor, bool isSocket)
return NULL;
}
- security_context_t tmp = NULL;
+ char* tmp = NULL;
int ret;
if (isSocket) {
ret = getpeercon(fd, &tmp);
@@ -184,7 +184,7 @@ static jstring getFdCon(JNIEnv *env, jobject, jobject fileDescriptor) {
* Function: setFSCreateCon
* Purpose: set security context used for creating a new file system object
* Parameters:
- * context: security_context_t representing the new context of a file system object,
+ * context: char* representing the new context of a file system object,
* set to NULL to return to the default policy behavior
* Returns: true on success, false on error
* Exception: none
@@ -267,7 +267,7 @@ static jstring getFileCon(JNIEnv *env, jobject, jstring pathStr) {
return NULL;
}
- security_context_t tmp = NULL;
+ char* tmp = NULL;
int ret = getfilecon(path.c_str(), &tmp);
Unique_SecurityContext context(tmp);
@@ -293,7 +293,7 @@ static jstring getCon(JNIEnv *env, jobject) {
return NULL;
}
- security_context_t tmp = NULL;
+ char* tmp = NULL;
int ret = getcon(&tmp);
Unique_SecurityContext context(tmp);
@@ -320,7 +320,7 @@ static jstring getPidCon(JNIEnv *env, jobject, jint pid) {
return NULL;
}
- security_context_t tmp = NULL;
+ char* tmp = NULL;
int ret = getpidcon(static_cast<pid_t>(pid), &tmp);
Unique_SecurityContext context(tmp);
diff --git a/core/res/Android.bp b/core/res/Android.bp
index e900eb2f01ab..bcc0a975b913 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -156,6 +156,7 @@ android_app {
generate_product_characteristics_rro: true,
flags_packages: [
+ "android.app.appfunctions.flags-aconfig",
"android.app.contextualsearch.flags-aconfig",
"android.content.pm.flags-aconfig",
"android.provider.flags-aconfig",
@@ -164,6 +165,7 @@ android_app {
"com.android.window.flags.window-aconfig",
"android.permission.flags-aconfig",
"android.os.flags-aconfig",
+ "android.os.vibrator.flags-aconfig",
"android.media.tv.flags-aconfig",
],
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 117041ab353e..160f651dbc5c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2617,7 +2617,8 @@
@hide
-->
<permission android:name="android.permission.VIBRATE_VENDOR_EFFECTS"
- android:protectionLevel="signature|privileged" />
+ android:protectionLevel="signature|privileged"
+ android:featureFlag="android.os.vibrator.vendor_vibration_effects" />
<!-- @SystemApi Allows access to the vibrator state.
<p>Protection level: signature
@@ -8010,6 +8011,41 @@
<permission android:name="android.permission.EXECUTE_APP_ACTION"
android:protectionLevel="internal|role" />
+ <!-- Must be required by an {@link android.app.appfunctions.AppFunctionService},
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") -->
+ <permission android:name="android.permission.BIND_APP_FUNCTION_SERVICE"
+ android:featureFlag="android.app.appfunctions.flags.enable_app_function_manager"
+ android:protectionLevel="signature" />
+
+ <!-- @SystemApi Allows a trusted application to perform actions on behalf of users inside of
+ applications with privacy guarantees from the system.
+ <p>This permission is currently only granted to system packages in the
+ {@link android.app.role.SYSTEM_UI_INTELLIGENCE} role which complies with privacy
+ requirements outlined in the Android CDD section "9.8.6 Content Capture".
+ <p>Apps are not able to opt-out from caller having this permission.
+ <p>Protection level: internal|role
+ @hide
+ @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") -->
+ <permission android:name="android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED"
+ android:featureFlag="android.app.appfunctions.flags.enable_app_function_manager"
+ android:protectionLevel="internal|role" />
+
+ <!-- @SystemApi Allows an application to perform actions on behalf of users inside of
+ applications.
+ <p>This permission is currently only granted to preinstalled / system apps having the
+ {@link android.app.role.ASSISTANT} role.
+ <p>Apps contributing app functions can opt to disallow callers with this permission,
+ limiting to only callers with {@link android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED}
+ instead.
+ <p>Protection level: internal|role
+ @hide
+ @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") -->
+ <permission android:name="android.permission.EXECUTE_APP_FUNCTIONS"
+ android:featureFlag="android.app.appfunctions.flags.enable_app_function_manager"
+ android:protectionLevel="internal|role" />
+
<!-- Allows an application to display its suggestions using the autofill framework.
<p>For now, this permission is only granted to the Browser application.
<p>Protection level: internal|role
diff --git a/core/res/res/drawable/ic_zen_mode_icon_lotus_flower.xml b/core/res/res/drawable/ic_zen_mode_icon_lotus_flower.xml
new file mode 100644
index 000000000000..c1afd44ecfc4
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_lotus_flower.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M480,880Q407,871 335,840.5Q263,810 206.5,753Q150,696 115,609Q80,522 80,400L80,360L120,360Q171,360 225,373Q279,386 326,412Q338,326 380.5,235.5Q423,145 480,80Q537,145 579.5,235.5Q622,326 634,412Q681,386 735,373Q789,360 840,360L880,360L880,400Q880,522 845,609Q810,696 753.5,753Q697,810 625.5,840.5Q554,871 480,880ZM478,798Q467,632 379.5,547Q292,462 162,442Q173,613 263.5,697Q354,781 478,798ZM480,544Q495,522 516.5,498.5Q538,475 558,458Q556,401 535.5,339Q515,277 480,218Q445,277 424.5,339Q404,401 402,458Q422,475 444,498.5Q466,522 480,544ZM558,780Q595,768 635,745Q675,722 709.5,682.5Q744,643 768.5,584Q793,525 798,442Q704,456 633,504.5Q562,553 524,628Q536,660 544.5,698Q553,736 558,780ZM480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544ZM558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780ZM478,798Q478,798 478,798Q478,798 478,798Q478,798 478,798Q478,798 478,798ZM524,628L524,628Q524,628 524,628Q524,628 524,628L524,628L524,628L524,628Q524,628 524,628Q524,628 524,628L524,628Q524,628 524,628Q524,628 524,628ZM480,880L480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880L480,880Q480,880 480,880Q480,880 480,880L480,880Q480,880 480,880Q480,880 480,880L480,880Z" />
+</vector> \ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_rabbit.xml b/core/res/res/drawable/ic_zen_mode_icon_rabbit.xml
deleted file mode 100644
index 190d0cb319ec..000000000000
--- a/core/res/res/drawable/ic_zen_mode_icon_rabbit.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2024 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:tint="?android:attr/colorControlNormal"
- android:viewportHeight="960"
- android:viewportWidth="960">
- <path
- android:fillColor="@android:color/white"
- android:pathData="M380,880Q305,880 252.5,827.5Q200,775 200,700Q200,665 217,635.5Q234,606 280,560Q286,554 291.5,547.5Q297,541 306,530Q255,452 227.5,366.5Q200,281 200,200Q200,142 221,111Q242,80 280,80Q337,80 382,135Q427,190 450,236Q459,256 466.5,276.5Q474,297 480,319Q486,297 493.5,276.5Q501,256 511,236Q533,190 578,135Q623,80 680,80Q718,80 739,111Q760,142 760,200Q760,281 732.5,366.5Q705,452 654,530Q663,541 668.5,547.5Q674,554 680,560Q726,606 743,635.5Q760,665 760,700Q760,775 707.5,827.5Q655,880 580,880Q535,880 507.5,870Q480,860 480,860Q480,860 452.5,870Q425,880 380,880ZM380,800Q403,800 426,794.5Q449,789 469,778Q458,773 449,761Q440,749 440,740Q440,732 451.5,726Q463,720 480,720Q497,720 508.5,726Q520,732 520,740Q520,749 511,761Q502,773 491,778Q511,789 534,794.5Q557,800 580,800Q622,800 651,771Q680,742 680,700Q680,682 670,665Q660,648 640,631Q626,619 617,610Q608,601 588,576Q559,541 540,530.5Q521,520 480,520Q439,520 419.5,530.5Q400,541 372,576Q352,601 343,610Q334,619 320,631Q300,648 290,665Q280,682 280,700Q280,742 309,771Q338,800 380,800ZM420,670Q412,670 406,661Q400,652 400,640Q400,628 406,619Q412,610 420,610Q428,610 434,619Q440,628 440,640Q440,652 434,661Q428,670 420,670ZM540,670Q532,670 526,661Q520,652 520,640Q520,628 526,619Q532,610 540,610Q548,610 554,619Q560,628 560,640Q560,652 554,661Q548,670 540,670ZM363,471Q374,463 388,457Q402,451 419,446Q417,398 404.5,350.5Q392,303 373,264Q354,224 331,196.5Q308,169 285,161Q283,167 281.5,176.5Q280,186 280,200Q280,268 301.5,338Q323,408 363,471ZM597,471Q637,408 658.5,338Q680,268 680,200Q680,186 678.5,176.5Q677,167 675,161Q652,169 629,196.5Q606,224 587,264Q569,303 556.5,350.5Q544,398 541,446Q556,450 570,456.5Q584,463 597,471Z" />
-</vector> \ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_type_unknown.xml b/core/res/res/drawable/ic_zen_mode_type_unknown.xml
index c1afd44ecfc4..04df5f91fd68 100644
--- a/core/res/res/drawable/ic_zen_mode_type_unknown.xml
+++ b/core/res/res/drawable/ic_zen_mode_type_unknown.xml
@@ -21,5 +21,5 @@ Copyright (C) 2024 The Android Open Source Project
android:viewportWidth="960">
<path
android:fillColor="@android:color/white"
- android:pathData="M480,880Q407,871 335,840.5Q263,810 206.5,753Q150,696 115,609Q80,522 80,400L80,360L120,360Q171,360 225,373Q279,386 326,412Q338,326 380.5,235.5Q423,145 480,80Q537,145 579.5,235.5Q622,326 634,412Q681,386 735,373Q789,360 840,360L880,360L880,400Q880,522 845,609Q810,696 753.5,753Q697,810 625.5,840.5Q554,871 480,880ZM478,798Q467,632 379.5,547Q292,462 162,442Q173,613 263.5,697Q354,781 478,798ZM480,544Q495,522 516.5,498.5Q538,475 558,458Q556,401 535.5,339Q515,277 480,218Q445,277 424.5,339Q404,401 402,458Q422,475 444,498.5Q466,522 480,544ZM558,780Q595,768 635,745Q675,722 709.5,682.5Q744,643 768.5,584Q793,525 798,442Q704,456 633,504.5Q562,553 524,628Q536,660 544.5,698Q553,736 558,780ZM480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544Q480,544 480,544ZM558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780Q558,780 558,780ZM478,798Q478,798 478,798Q478,798 478,798Q478,798 478,798Q478,798 478,798ZM524,628L524,628Q524,628 524,628Q524,628 524,628L524,628L524,628L524,628Q524,628 524,628Q524,628 524,628L524,628Q524,628 524,628Q524,628 524,628ZM480,880L480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880Q480,880 480,880L480,880Q480,880 480,880Q480,880 480,880L480,880Q480,880 480,880Q480,880 480,880L480,880Z" />
+ android:pathData="M368,640L480,556L590,640L548,504L660,416L524,416L480,280L436,416L300,416L410,504L368,640ZM160,800Q127,800 103.5,776.5Q80,753 80,720L80,585Q80,574 87,566Q94,558 105,556Q129,548 144.5,527Q160,506 160,480Q160,454 144.5,433Q129,412 105,404Q94,402 87,394Q80,386 80,375L80,240Q80,207 103.5,183.5Q127,160 160,160L800,160Q833,160 856.5,183.5Q880,207 880,240L880,375Q880,386 873,394Q866,402 855,404Q831,412 815.5,433Q800,454 800,480Q800,506 815.5,527Q831,548 855,556Q866,558 873,566Q880,574 880,585L880,720Q880,753 856.5,776.5Q833,800 800,800L160,800ZM160,720L800,720Q800,720 800,720Q800,720 800,720L800,618Q763,596 741.5,559.5Q720,523 720,480Q720,437 741.5,400.5Q763,364 800,342L800,240Q800,240 800,240Q800,240 800,240L160,240Q160,240 160,240Q160,240 160,240L160,342Q197,364 218.5,400.5Q240,437 240,480Q240,523 218.5,559.5Q197,596 160,618L160,720Q160,720 160,720Q160,720 160,720ZM480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Z" />
</vector> \ No newline at end of file
diff --git a/core/res/res/layout/input_method_switch_dialog_new.xml b/core/res/res/layout/input_method_switch_dialog_new.xml
index 610a212bbd4e..058fe3fe3076 100644
--- a/core/res/res/layout/input_method_switch_dialog_new.xml
+++ b/core/res/res/layout/input_method_switch_dialog_new.xml
@@ -71,9 +71,10 @@
android:layout_height="wrap_content"
android:background="@drawable/input_method_switch_button"
android:layout_gravity="end"
- android:text="@string/input_method_language_settings"
+ android:text="@string/input_method_switcher_settings_button"
android:fontFamily="google-sans-text"
android:textAppearance="?attr/textAppearance"
+ android:contentDescription="@string/input_method_language_settings"
android:visibility="gone"/>
</LinearLayout>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index cb58339f5ef3..f40466610724 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3280,6 +3280,9 @@
<!-- Accessibility text for the long click action on the switch input method button. This will
be used following "Double-tap and hold to..." [CHAR LIMIT=NONE] -->
<string name="input_method_ime_switch_long_click_action_desc">Open input method picker</string>
+ <!-- Button to access the language settings of the current input method
+ from the Input Method Switcher menu. [CHAR LIMIT=50]-->
+ <string name="input_method_switcher_settings_button">Settings</string>
<!-- If the device is getting low on internal storage, a notification is shown to the user. This is the title of that notification. -->
<string name="low_internal_storage_view_title">Storage space running out</string>
@@ -3883,7 +3886,8 @@
<!-- Title of the pop-up dialog in which the user switches keyboard, also known as input method. -->
<string name="select_input_method">Choose input method</string>
- <!-- Button to access the language settings of the current input method. [CHAR LIMIT=50]-->
+ <!-- Content description of the button to access the language settings of the current input method
+ from the Input Method Switcher menu, for accessibility (not shown on the screen). [CHAR LIMIT=NONE]-->
<string name="input_method_language_settings">Language Settings</string>
<!-- Summary text of a toggle switch to enable/disable use of the IME while a physical
keyboard is connected -->
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index f5c67387cb92..452ae04c7199 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -212,30 +212,30 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
<item name="colorPopupBackground">?attr/colorBackgroundFloating</item>
<item name="panelColorBackground">?attr/colorBackgroundFloating</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -314,28 +314,28 @@ easier.
<style name="Theme.DeviceDefault.NoActionBar" parent="Theme.Material.NoActionBar">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -431,28 +431,28 @@ easier.
<style name="Theme.DeviceDefault.NoActionBar.Fullscreen" parent="Theme.Material.NoActionBar.Fullscreen">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -550,28 +550,28 @@ easier.
<style name="Theme.DeviceDefault.NoActionBar.Overscan" parent="Theme.Material.NoActionBar.Overscan">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -668,28 +668,28 @@ easier.
<style name="Theme.DeviceDefault.NoActionBar.TranslucentDecor" parent="Theme.Material.NoActionBar.TranslucentDecor">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -801,28 +801,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -911,28 +911,28 @@ easier.
<style name="Theme.DeviceDefault.Dialog.MinWidth" parent="Theme.Material.Dialog.MinWidth">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1027,28 +1027,28 @@ easier.
<style name="Theme.DeviceDefault.Dialog.NoActionBar" parent="Theme.Material.Dialog.NoActionBar">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1144,28 +1144,28 @@ easier.
<style name="Theme.DeviceDefault.Dialog.NoActionBar.MinWidth" parent="Theme.Material.Dialog.NoActionBar.MinWidth">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1277,28 +1277,28 @@ easier.
<style name="Theme.DeviceDefault.DialogWhenLarge" parent="Theme.Material.DialogWhenLarge">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1395,28 +1395,28 @@ easier.
<style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" parent="Theme.Material.DialogWhenLarge.NoActionBar">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1511,28 +1511,28 @@ easier.
<style name="Theme.DeviceDefault.Dialog.Presentation" parent="Theme.Material.Dialog.Presentation">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1629,28 +1629,28 @@ easier.
<style name="Theme.DeviceDefault.Panel" parent="Theme.Material.Panel">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1746,28 +1746,28 @@ easier.
<style name="Theme.DeviceDefault.Wallpaper" parent="Theme.Material.Wallpaper">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1863,28 +1863,28 @@ easier.
<style name="Theme.DeviceDefault.Wallpaper.NoTitleBar" parent="Theme.Material.Wallpaper.NoTitleBar">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -1980,28 +1980,28 @@ easier.
<style name="Theme.DeviceDefault.InputMethod" parent="Theme.Material.InputMethod">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -2097,28 +2097,28 @@ easier.
<style name="Theme.DeviceDefault.VoiceInteractionSession" parent="Theme.Material.VoiceInteractionSession">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -2218,28 +2218,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -2336,28 +2336,28 @@ easier.
<style name="Theme.DeviceDefault.SearchBar" parent="Theme.Material.SearchBar">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -2451,28 +2451,28 @@ easier.
<style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -2720,28 +2720,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
<item name="colorPopupBackground">?attr/colorBackgroundFloating</item>
@@ -2821,28 +2821,28 @@ easier.
<style name="Theme.DeviceDefault.Light.DarkActionBar" parent="Theme.Material.Light.DarkActionBar">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -2937,28 +2937,28 @@ easier.
<style name="Theme.DeviceDefault.Light.NoActionBar" parent="Theme.Material.Light.NoActionBar">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -3054,28 +3054,28 @@ easier.
<style name="Theme.DeviceDefault.Light.NoActionBar.Fullscreen" parent="Theme.Material.Light.NoActionBar.Fullscreen">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -3173,28 +3173,28 @@ easier.
<style name="Theme.DeviceDefault.Light.NoActionBar.Overscan" parent="Theme.Material.Light.NoActionBar.Overscan">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -3291,28 +3291,28 @@ easier.
<style name="Theme.DeviceDefault.Light.NoActionBar.TranslucentDecor" parent="Theme.Material.Light.NoActionBar.TranslucentDecor">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -3426,28 +3426,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -3535,28 +3535,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -3654,28 +3654,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -3774,28 +3774,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -3895,26 +3895,26 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -3996,26 +3996,26 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -4096,28 +4096,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -4217,28 +4217,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -4336,28 +4336,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -4454,28 +4454,28 @@ easier.
<style name="Theme.DeviceDefault.Light.Panel" parent="Theme.Material.Light.Panel">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -4571,28 +4571,28 @@ easier.
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -4688,28 +4688,28 @@ easier.
<style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Material.Light.SearchBar">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -4803,28 +4803,28 @@ easier.
<style name="Theme.DeviceDefault.Light.Voice" parent="Theme.Material.Light.Voice">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_light</item>
- <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
+ <item name="colorPrimaryDark">@color/primary_device_default_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -4932,21 +4932,21 @@ easier.
<item name="popupTheme">@style/ThemeOverlay.DeviceDefault.Popup.Light</item>
<!-- Color palette -->
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorPrimary">@color/primary_device_default_settings_light</item>
<item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
<item name="colorSecondary">@color/secondary_device_default_settings_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
<item name="colorEdgeEffect">@color/edge_effect_device_default_light</item>
@@ -5044,16 +5044,16 @@ easier.
<item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
<item name="colorSecondary">@color/secondary_device_default_settings_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
<item name="colorControlNormal">?attr/textColorPrimary</item>
<item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
@@ -5148,16 +5148,16 @@ easier.
<item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
<item name="colorSecondary">@color/secondary_device_default_settings_light</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
<item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
@@ -5245,26 +5245,26 @@ easier.
<item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
<item name="colorSecondary">@color/secondary_device_default_settings</item>
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_dark_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_dark_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_dark_device_default</item>
- <item name="colorSurface">@color/surface_dark</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_dark</item>
- <item name="colorSurfaceVariant">@color/surface_variant_dark</item>
- <item name="colorSurfaceHeader">@color/surface_header_dark</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_dark</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_dark</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_dark</item>
+ <item name="colorSurface">@color/system_surface_container_dark</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_dark</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_dark</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_dark</item>
<item name="colorError">@color/error_color_device_default_dark</item>
- <item name="colorBackground">@color/background_device_default_dark</item>
+ <item name="colorBackground">@color/system_surface_container_dark</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_dark</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_dark</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiary">@color/system_outline_dark</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_light</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_light</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
@@ -5361,26 +5361,26 @@ easier.
<item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
<item name="colorSecondary">@color/secondary_device_default_settings</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -5487,26 +5487,26 @@ easier.
<item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
<item name="colorSecondary">@color/secondary_device_default_settings</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -5606,26 +5606,26 @@ easier.
<item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
<item name="colorSecondary">@color/secondary_device_default_settings</item>
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
- <item name="colorAccentPrimaryVariant">@color/accent_primary_variant_light_device_default</item>
- <item name="colorAccentSecondaryVariant">@color/accent_secondary_variant_light_device_default</item>
- <item name="colorAccentTertiaryVariant">@color/accent_tertiary_variant_light_device_default</item>
- <item name="colorSurface">@color/surface_light</item>
- <item name="colorSurfaceHighlight">@color/surface_highlight_light</item>
- <item name="colorSurfaceVariant">@color/surface_variant_light</item>
- <item name="colorSurfaceHeader">@color/surface_header_light</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
+ <item name="colorAccentPrimaryVariant">@color/system_primary_container_light</item>
+ <item name="colorAccentSecondaryVariant">@color/system_secondary_container_light</item>
+ <item name="colorAccentTertiaryVariant">@color/system_tertiary_container_light</item>
+ <item name="colorSurface">@color/system_surface_container_light</item>
+ <item name="colorSurfaceHighlight">@color/system_surface_bright_light</item>
+ <item name="colorSurfaceVariant">@color/system_surface_container_high_light</item>
+ <item name="colorSurfaceHeader">@color/system_surface_container_highest_light</item>
<item name="colorError">@color/error_color_device_default_light</item>
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
- <item name="textColorPrimary">@color/text_color_primary_device_default_light</item>
- <item name="textColorSecondary">@color/text_color_secondary_device_default_light</item>
- <item name="textColorTertiary">@color/text_color_tertiary_device_default_light</item>
- <item name="textColorPrimaryInverse">@color/text_color_primary_device_default_dark</item>
- <item name="textColorSecondaryInverse">@color/text_color_secondary_device_default_dark</item>
- <item name="textColorTertiaryInverse">@color/text_color_tertiary_device_default_dark</item>
- <item name="textColorOnAccent">@color/text_color_on_accent_device_default</item>
+ <item name="textColorPrimary">@color/system_on_surface_light</item>
+ <item name="textColorSecondary">@color/system_on_surface_variant_light</item>
+ <item name="textColorTertiary">@color/system_outline_light</item>
+ <item name="textColorPrimaryInverse">@color/system_on_surface_dark</item>
+ <item name="textColorSecondaryInverse">@color/system_on_surface_variant_dark</item>
+ <item name="textColorTertiaryInverse">@color/system_outline_dark</item>
+ <item name="textColorOnAccent">@color/system_on_primary_dark</item>
<item name="colorForeground">@color/foreground_device_default_light</item>
<item name="colorForegroundInverse">@color/foreground_device_default_dark</item>
@@ -5788,9 +5788,9 @@ easier.
<style name="ThemeOverlay.DeviceDefault.Accent">
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
<item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
<item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
@@ -5863,9 +5863,9 @@ easier.
<style name="ThemeOverlay.DeviceDefault.Accent.Light">
<item name="colorAccent">@color/accent_device_default_light</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
<item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
<item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
@@ -5938,13 +5938,13 @@ easier.
<!-- Theme overlay that replaces colorAccent with the colorAccent from {@link #Theme_DeviceDefault_DayNight}. -->
<style name="ThemeOverlay.DeviceDefault.Accent.DayNight"
- parent="@style/ThemeOverlay.DeviceDefault.Accent.Light" />
+ parent="@style/ThemeOverlay.DeviceDefault.Accent.Light" />
<style name="ThemeOverlay.DeviceDefault.Dark.ActionBar.Accent" parent="ThemeOverlay.Material.Dark.ActionBar">
<item name="colorAccent">@color/accent_device_default_dark</item>
- <item name="colorAccentPrimary">@color/accent_primary_device_default</item>
- <item name="colorAccentSecondary">@color/accent_secondary_device_default</item>
- <item name="colorAccentTertiary">@color/accent_tertiary_device_default</item>
+ <item name="colorAccentPrimary">@color/system_primary_dark</item>
+ <item name="colorAccentSecondary">@color/system_secondary_dark</item>
+ <item name="colorAccentTertiary">@color/system_tertiary_dark</item>
<item name="materialColorOnSecondaryFixedVariant">@color/system_on_secondary_fixed_variant</item>
<item name="materialColorOnTertiaryFixedVariant">@color/system_on_tertiary_fixed_variant</item>
@@ -6016,7 +6016,7 @@ easier.
</style>
<style name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" parent="Theme.DeviceDefault.NoActionBar.Fullscreen">
- <item name="colorBackground">@color/background_device_default_light</item>
+ <item name="colorBackground">@color/system_surface_container_light</item>
<item name="colorBackgroundFloating">@color/background_device_default_light</item>
<item name="layout_gravity">center</item>
<item name="windowAnimationStyle">@style/Animation.DeviceDefault.Dialog</item>
diff --git a/core/tests/coretests/src/android/view/ViewFrameRateTest.java b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
index b8ff59528b24..c631c6f46e37 100644
--- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java
+++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
@@ -994,6 +994,35 @@ public class ViewFrameRateTest {
mViewRoot.getLastPreferredFrameRateCategory());
}
+ /**
+ * If a View is an instance of ViewGroupOverlay,
+ * we obtain the velocity from its hostView.
+ */
+ @Test
+ @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
+ public void overlayViewGroupVelocity() throws Throwable {
+ if (!ViewProperties.vrr_enabled().orElse(true)) {
+ return;
+ }
+
+ FrameLayout host = new FrameLayout(mActivity);
+ View childView = new View(mActivity);
+ float velocity = 1000;
+
+ mActivityRule.runOnUiThread(() -> {
+ ViewGroup.LayoutParams fullSize = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mActivity.setContentView(host, fullSize);
+ host.setFrameContentVelocity(velocity);
+ ViewGroupOverlay overlay = host.getOverlay();
+ overlay.add(childView);
+ assertEquals(velocity, host.getFrameContentVelocity());
+ assertEquals(host.getFrameContentVelocity(),
+ ((View) childView.getParent()).getFrameContentVelocity());
+ });
+ }
+
private void runAfterDraw(@NonNull Runnable runnable) {
Handler handler = new Handler(Looper.getMainLooper());
mAfterDrawLatch = new CountDownLatch(1);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/BackupHelper.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/BackupHelper.java
new file mode 100644
index 000000000000..69a68c85a2fe
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/BackupHelper.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window.extensions.embedding;
+
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Looper;
+import android.os.MessageQueue;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.util.List;
+
+/**
+ * Helper class to back up and restore the TaskFragmentOrganizer state, in order to resume
+ * organizing the TaskFragments if the app process is restarted.
+ */
+@SuppressWarnings("GuardedBy")
+class BackupHelper {
+ private static final String TAG = "BackupHelper";
+ private static final boolean DEBUG = Build.isDebuggable();
+
+ private static final String KEY_TASK_CONTAINERS = "KEY_TASK_CONTAINERS";
+ @NonNull
+ private final SplitController mController;
+ @NonNull
+ private final BackupIdler mBackupIdler = new BackupIdler();
+ private boolean mBackupIdlerScheduled;
+
+ BackupHelper(@NonNull SplitController splitController, @NonNull Bundle savedState) {
+ mController = splitController;
+
+ if (!savedState.isEmpty()) {
+ restoreState(savedState);
+ }
+ }
+
+ /**
+ * Schedules a back-up request. It is no-op if there was a request scheduled and not yet
+ * completed.
+ */
+ void scheduleBackup() {
+ if (!mBackupIdlerScheduled) {
+ mBackupIdlerScheduled = true;
+ Looper.myQueue().addIdleHandler(mBackupIdler);
+ }
+ }
+
+ final class BackupIdler implements MessageQueue.IdleHandler {
+ @Override
+ public boolean queueIdle() {
+ synchronized (mController.mLock) {
+ mBackupIdlerScheduled = false;
+ startBackup();
+ }
+ return false;
+ }
+ }
+
+ private void startBackup() {
+ final List<TaskContainer> taskContainers = mController.getTaskContainers();
+ if (taskContainers.isEmpty()) {
+ Log.w(TAG, "No task-container to back up");
+ return;
+ }
+
+ if (DEBUG) Log.d(TAG, "Start to back up " + taskContainers);
+ final Bundle state = new Bundle();
+ state.setClassLoader(TaskContainer.class.getClassLoader());
+ state.putParcelableList(KEY_TASK_CONTAINERS, taskContainers);
+ mController.setSavedState(state);
+ }
+
+ private void restoreState(@NonNull Bundle savedState) {
+ if (savedState.isEmpty()) {
+ return;
+ }
+
+ final List<TaskContainer> taskContainers = savedState.getParcelableArrayList(
+ KEY_TASK_CONTAINERS, TaskContainer.class);
+ for (TaskContainer taskContainer : taskContainers) {
+ if (DEBUG) Log.d(TAG, "restore task " + taskContainer.getTaskId());
+ // TODO(b/289875940): implement the TaskContainer restoration.
+ }
+ }
+}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 26d180cdcb1a..bb384c5d0e84 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -2536,6 +2536,21 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return mTaskContainers.get(taskId);
}
+ @NonNull
+ @GuardedBy("mLock")
+ List<TaskContainer> getTaskContainers() {
+ final ArrayList<TaskContainer> taskContainers = new ArrayList<>();
+ for (int i = mTaskContainers.size() - 1; i >= 0; i--) {
+ taskContainers.add(mTaskContainers.valueAt(i));
+ }
+ return taskContainers;
+ }
+
+ @GuardedBy("mLock")
+ void setSavedState(@NonNull Bundle savedState) {
+ mPresenter.setSavedState(savedState);
+ }
+
@GuardedBy("mLock")
void addTaskContainer(int taskId, TaskContainer taskContainer) {
mTaskContainers.put(taskId, taskContainer);
@@ -2829,6 +2844,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
return getActiveSplitForContainer(container) != null;
}
+ void scheduleBackup() {
+ synchronized (mLock) {
+ mPresenter.scheduleBackup();
+ }
+ }
+
private final class LifecycleCallbacks extends EmptyLifecycleCallbacksAdapter {
@Override
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 99716e7cc69e..fb8efc4ad490 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -158,6 +158,8 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
private final WindowLayoutComponentImpl mWindowLayoutComponent;
private final SplitController mController;
+ @NonNull
+ private final BackupHelper mBackupHelper;
SplitPresenter(@NonNull Executor executor,
@NonNull WindowLayoutComponentImpl windowLayoutComponent,
@@ -165,7 +167,18 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer {
super(executor, controller);
mWindowLayoutComponent = windowLayoutComponent;
mController = controller;
- registerOrganizer();
+ final Bundle outSavedState = new Bundle();
+ if (Flags.aeBackStackRestore()) {
+ outSavedState.setClassLoader(TaskContainer.class.getClassLoader());
+ registerOrganizer(false /* isSystemOrganizer */, outSavedState);
+ } else {
+ registerOrganizer();
+ }
+ mBackupHelper = new BackupHelper(controller, outSavedState);
+ }
+
+ void scheduleBackup() {
+ mBackupHelper.scheduleBackup();
}
/**
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
index 20ad53ee19a8..5795e8da18c2 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
@@ -32,6 +32,8 @@ import android.app.WindowConfiguration.WindowingMode;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -48,12 +50,14 @@ import androidx.window.extensions.embedding.SplitAttributes.SplitType;
import androidx.window.extensions.embedding.SplitAttributes.SplitType.ExpandContainersSplitType;
import androidx.window.extensions.embedding.SplitAttributes.SplitType.RatioSplitType;
+import com.android.window.flags.Flags;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/** Represents TaskFragments and split pairs below a Task. */
-class TaskContainer {
+class TaskContainer implements Parcelable {
private static final String TAG = TaskContainer.class.getSimpleName();
/** The unique task id. */
@@ -80,6 +84,9 @@ class TaskContainer {
@NonNull
private TaskFragmentParentInfo mInfo;
+ @NonNull
+ private SplitController mSplitController;
+
/**
* TaskFragments that the organizer has requested to be closed. They should be removed when
* the organizer receives
@@ -116,12 +123,14 @@ class TaskContainer {
/**
* The {@link TaskContainer} constructor
*
- * @param taskId The ID of the Task, which must match {@link Activity#getTaskId()} with
- * {@code activityInTask}.
- * @param activityInTask The {@link Activity} in the Task with {@code taskId}. It is used to
- * initialize the {@link TaskContainer} properties.
+ * @param taskId The ID of the Task, which must match {@link Activity#getTaskId()} with
+ * {@code activityInTask}.
+ * @param activityInTask The {@link Activity} in the Task with {@code taskId}. It is used to
+ * initialize the {@link TaskContainer} properties.
+ * @param splitController The {@link SplitController}.
*/
- TaskContainer(int taskId, @NonNull Activity activityInTask) {
+ TaskContainer(int taskId, @NonNull Activity activityInTask,
+ @Nullable SplitController splitController) {
if (taskId == INVALID_TASK_ID) {
throw new IllegalArgumentException("Invalid Task id");
}
@@ -136,6 +145,7 @@ class TaskContainer {
true /* visible */,
true /* hasDirectActivity */,
null /* decorSurface */);
+ mSplitController = splitController;
}
int getTaskId() {
@@ -571,6 +581,12 @@ class TaskContainer {
// Update overlay container after split pin container since the overlay should be on top of
// pin container.
updateAlwaysOnTopOverlayIfNecessary();
+
+ // TODO(b/289875940): Making backup-restore as an opt-in solution, before the flag goes
+ // to next-food.
+ if (Flags.aeBackStackRestore()) {
+ mSplitController.scheduleBackup();
+ }
}
private void updateAlwaysOnTopOverlayIfNecessary() {
@@ -664,6 +680,34 @@ class TaskContainer {
return activityStacks;
}
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mTaskId);
+ // TODO(b/289875940)
+ }
+
+ protected TaskContainer(Parcel in) {
+ mTaskId = in.readInt();
+ // TODO(b/289875940)
+ }
+
+ public static final Creator<TaskContainer> CREATOR = new Creator<>() {
+ @Override
+ public TaskContainer createFromParcel(Parcel in) {
+ return new TaskContainer(in);
+ }
+
+ @Override
+ public TaskContainer[] newArray(int size) {
+ return new TaskContainer[size];
+ }
+ };
+
/** A wrapper class which contains the information of {@link TaskContainer} */
static final class TaskProperties {
private final int mDisplayId;
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index ee3e6f368505..dc6506b070af 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -1203,7 +1203,7 @@ class TaskFragmentContainer {
if (taskContainer == null) {
// Adding a TaskContainer if no existed one.
- taskContainer = new TaskContainer(mTaskId, mActivityInTask);
+ taskContainer = new TaskContainer(mTaskId, mActivityInTask, mSplitController);
mSplitController.addTaskContainer(mTaskId, taskContainer);
}
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
index 7dc78fdd601f..5c85778ee42d 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java
@@ -222,7 +222,7 @@ public class EmbeddingTestUtils {
doReturn(resources).when(activity).getResources();
doReturn(DEFAULT_DISPLAY).when(activity).getDisplayId();
- return new TaskContainer(TASK_ID, activity);
+ return new TaskContainer(TASK_ID, activity, mock(SplitController.class));
}
static TaskContainer createTestTaskContainer(@NonNull SplitController controller) {
diff --git a/libs/WindowManager/Shell/res/layout/compat_ui_restart_button_layout.xml b/libs/WindowManager/Shell/res/layout/compat_ui_restart_button_layout.xml
new file mode 100644
index 000000000000..d00c69cb2993
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/compat_ui_restart_button_layout.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="bottom|end">
+
+ <include android:id="@+id/size_compat_hint"
+ android:visibility="gone"
+ android:layout_width="@dimen/compat_hint_width"
+ android:layout_height="wrap_content"
+ layout="@layout/compat_mode_hint"/>
+
+ <ImageButton
+ android:id="@+id/size_compat_restart_button"
+ android:visibility="gone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/compat_button_margin"
+ android:layout_marginBottom="@dimen/compat_button_margin"
+ android:src="@drawable/size_compat_restart_button_ripple"
+ android:background="@android:color/transparent"
+ android:contentDescription="@string/restart_button_description"/>
+
+</LinearLayout>
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java
index ebca5df63c15..498dc8bdd24d 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/split/SplitScreenConstants.java
@@ -30,7 +30,7 @@ public class SplitScreenConstants {
/** Duration used for every split fade-in or fade-out. */
public static final int FADE_DURATION = 133;
/** Duration where we keep an app veiled to allow it to redraw itself behind the scenes. */
- public static final int VEIL_DELAY_DURATION = 400;
+ public static final int VEIL_DELAY_DURATION = 300;
/** Key for passing in widget intents when invoking split from launcher workspace. */
public static final String KEY_EXTRA_WIDGET_INTENT = "key_extra_widget_intent";
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java
index d754d04e6b33..26f7b360e0fc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java
@@ -20,6 +20,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.graphics.Color;
import android.graphics.Rect;
import android.view.SurfaceControl;
@@ -59,6 +60,23 @@ public class BackAnimationBackground {
*/
public void ensureBackground(Rect startRect, int color,
@NonNull SurfaceControl.Transaction transaction, int statusbarHeight) {
+ ensureBackground(startRect, color, transaction, statusbarHeight,
+ null /* cropBounds */, 0 /* cornerRadius */);
+ }
+
+ /**
+ * Ensures the back animation background color layer is present.
+ *
+ * @param startRect The start bounds of the closing target.
+ * @param color The background color.
+ * @param transaction The animation transaction.
+ * @param statusbarHeight The height of the statusbar (in px).
+ * @param cropBounds The crop bounds of the surface, set to non-empty to show wallpaper.
+ * @param cornerRadius The radius of corner, only work when cropBounds is not empty.
+ */
+ public void ensureBackground(Rect startRect, int color,
+ @NonNull SurfaceControl.Transaction transaction, int statusbarHeight,
+ @Nullable Rect cropBounds, float cornerRadius) {
if (mBackgroundSurface != null) {
return;
}
@@ -78,6 +96,10 @@ public class BackAnimationBackground {
transaction.setColor(mBackgroundSurface, colorComponents)
.setLayer(mBackgroundSurface, BACKGROUND_LAYER)
.show(mBackgroundSurface);
+ if (cropBounds != null && !cropBounds.isEmpty()) {
+ transaction.setCrop(mBackgroundSurface, cropBounds)
+ .setCornerRadius(mBackgroundSurface, cornerRadius);
+ }
mStartBounds = startRect;
mIsRequestingStatusBarAppearance = false;
mStatusbarHeight = statusbarHeight;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 356ecb3358db..d7da0515f228 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -1313,15 +1313,18 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
info.getChanges().remove(j);
}
}
- tmpSize = info.getChanges().size();
- for (int i = 0; i < tmpSize; ++i) {
- final TransitionInfo.Change change = init.getChanges().get(i);
- if (moveToTop) {
- if (isSameChangeTarget(openComponent, openTaskId, change)) {
- change.setFlags(change.getFlags() | FLAG_MOVED_TO_TOP);
+ // Ignore merge if there is no close target
+ if (!info.getChanges().isEmpty()) {
+ tmpSize = init.getChanges().size();
+ for (int i = 0; i < tmpSize; ++i) {
+ final TransitionInfo.Change change = init.getChanges().get(i);
+ if (moveToTop) {
+ if (isSameChangeTarget(openComponent, openTaskId, change)) {
+ change.setFlags(change.getFlags() | FLAG_MOVED_TO_TOP);
+ }
}
+ info.getChanges().add(i, change);
}
- info.getChanges().add(i, change);
}
} else {
// Open transition, the transition info should be:
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index 4fd8b8a5f1b8..32e809a23a91 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -189,10 +189,13 @@ abstract class CrossActivityBackAnimation(
preparePreCommitEnteringRectMovement()
background.ensureBackground(
- closingTarget!!.windowConfiguration.bounds,
- getBackgroundColor(),
- transaction,
- statusbarHeight
+ closingTarget!!.windowConfiguration.bounds,
+ getBackgroundColor(),
+ transaction,
+ statusbarHeight,
+ if (closingTarget!!.windowConfiguration.tasksAreFloating())
+ closingTarget!!.localBounds else null,
+ cornerRadius
)
ensureScrimLayer()
if (isLetterboxed && enteringHasSameLetterbox) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index e807afbb1e03..2a934cba1b50 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -27,6 +27,8 @@ import static android.view.WindowManager.DOCKED_TOP;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE;
import static com.android.wm.shell.shared.animation.Interpolators.DIM_INTERPOLATOR;
+import static com.android.wm.shell.shared.animation.Interpolators.EMPHASIZED;
+import static com.android.wm.shell.shared.animation.Interpolators.LINEAR;
import static com.android.wm.shell.shared.animation.Interpolators.SLOWDOWN_INTERPOLATOR;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS;
@@ -813,7 +815,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
float growPortion = 1 - shrinkPortion;
ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
- animator.setInterpolator(Interpolators.EMPHASIZED);
+ // Set the base animation to proceed linearly. Each component of the animation (movement,
+ // shrinking, growing) overrides it with a different interpolator later.
+ animator.setInterpolator(LINEAR);
animator.addUpdateListener(animation -> {
if (leash == null) return;
if (roundCorners) {
@@ -822,10 +826,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
}
final float progress = (float) animation.getAnimatedValue();
- float instantaneousX = tempStart.left + progress * diffX;
- float instantaneousY = tempStart.top + progress * diffY;
- int width = (int) (tempStart.width() + progress * diffWidth);
- int height = (int) (tempStart.height() + progress * diffHeight);
+ final float moveProgress = EMPHASIZED.getInterpolation(progress);
+ float instantaneousX = tempStart.left + moveProgress * diffX;
+ float instantaneousY = tempStart.top + moveProgress * diffY;
+ int width = (int) (tempStart.width() + moveProgress * diffWidth);
+ int height = (int) (tempStart.height() + moveProgress * diffHeight);
if (isGoingBehind) {
float shrinkDiffX; // the position adjustments needed for this frame
@@ -897,8 +902,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
taskInfo, mTempRect, t, isGoingBehind, leash, 0, 0);
}
} else {
- final int diffOffsetX = (int) (progress * offsetX);
- final int diffOffsetY = (int) (progress * offsetY);
+ final int diffOffsetX = (int) (moveProgress * offsetX);
+ final int diffOffsetY = (int) (moveProgress * offsetY);
t.setPosition(leash, instantaneousX + diffOffsetX, instantaneousY + diffOffsetY);
mTempRect.set(0, 0, width, height);
mTempRect.offsetTo(-diffOffsetX, -diffOffsetY);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponent.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponent.kt
index 9ee50ac3c221..831b331a11e9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponent.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponent.kt
@@ -16,28 +16,222 @@
package com.android.wm.shell.compatui.api
-import android.util.Log
+import android.content.Context
+import android.content.res.Configuration
+import android.graphics.PixelFormat
+import android.graphics.Point
+import android.os.Binder
+import android.view.IWindow
+import android.view.SurfaceControl
+import android.view.SurfaceControlViewHost
+import android.view.SurfaceSession
+import android.view.View
+import android.view.WindowManager
+import android.view.WindowlessWindowManager
+import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.common.SyncTransactionQueue
/**
* The component created after a {@link CompatUISpec} definition
*/
class CompatUIComponent(
private val spec: CompatUISpec,
- private val id: String
+ private val id: String,
+ private var context: Context,
+ private val state: CompatUIState,
+ private var compatUIInfo: CompatUIInfo,
+ private val syncQueue: SyncTransactionQueue,
+ private var displayLayout: DisplayLayout?
+) : WindowlessWindowManager(
+ compatUIInfo.taskInfo.configuration,
+ /* rootSurface */
+ null,
+ /* hostInputToken */
+ null
) {
+ private val tag
+ get() = "CompatUI {id = $id}"
+
+ private var leash: SurfaceControl? = null
+
+ private var layout: View? = null
+
+ /**
+ * Utility class for adding and releasing a View hierarchy for this [ ] to `mLeash`.
+ */
+ protected var viewHost: SurfaceControlViewHost? = null
+
+ override fun setConfiguration(configuration: Configuration?) {
+ super.setConfiguration(configuration)
+ configuration?.let {
+ context = context.createConfigurationContext(it)
+ }
+ }
+
/**
* Invoked every time a new CompatUIInfo comes from core
* @param newInfo The new CompatUIInfo object
- * @param sharedState The state shared between all the component
*/
- fun update(newInfo: CompatUIInfo, state: CompatUIState) {
- // TODO(b/322817374): To be removed when the implementation is provided.
- Log.d("CompatUIComponent", "update() newInfo: $newInfo state:$state")
+ fun update(newInfo: CompatUIInfo) {
+ updateComponentState(newInfo, state.stateForComponent(id))
+ updateUI(state)
}
fun release() {
- // TODO(b/322817374): To be removed when the implementation is provided.
- Log.d("CompatUIComponent", "release()")
+ spec.log("$tag releasing.....")
+ // Implementation empty
+ // Hiding before releasing to avoid flickering when transitioning to the Home screen.
+ layout?.visibility = View.GONE
+ layout = null
+ spec.layout.viewReleaser()
+ spec.log("$tag layout releaser invoked!")
+ viewHost?.release()
+ viewHost = null
+ leash?.run {
+ val localLeash: SurfaceControl = this
+ syncQueue.runInSync { t: SurfaceControl.Transaction ->
+ t.remove(
+ localLeash
+ )
+ }
+ leash = null
+ spec.log("$tag leash removed")
+ }
+ spec.log("$tag released")
+ }
+
+ override fun getParentSurface(
+ window: IWindow,
+ attrs: WindowManager.LayoutParams
+ ): SurfaceControl? {
+ val className = javaClass.simpleName
+ val builder = SurfaceControl.Builder(SurfaceSession())
+ .setContainerLayer()
+ .setName(className + "Leash")
+ .setHidden(false)
+ .setCallsite("$className#attachToParentSurface")
+ attachToParentSurface(builder)
+ leash = builder.build()
+ initSurface(leash)
+ return leash
+ }
+
+ fun attachToParentSurface(builder: SurfaceControl.Builder) {
+ compatUIInfo.listener?.attachChildSurfaceToTask(compatUIInfo.taskInfo.taskId, builder)
+ }
+
+ fun initLayout(newCompatUIInfo: CompatUIInfo) {
+ compatUIInfo = newCompatUIInfo
+ spec.log("$tag updating...")
+ check(viewHost == null) { "A UI has already been created with this window manager." }
+ val componentState: CompatUIComponentState? = state.stateForComponent(id)
+ spec.log("$tag state: $componentState")
+ // We inflate the layout
+ layout = spec.layout.viewBuilder(context, compatUIInfo, componentState)
+ spec.log("$tag layout: $layout")
+ viewHost = createSurfaceViewHost().apply {
+ spec.log("$tag adding view $layout to host $this")
+ setView(layout!!, getWindowLayoutParams())
+ }
+ updateSurfacePosition()
+ }
+
+ /** Creates a [SurfaceControlViewHost] for this window manager. */
+ fun createSurfaceViewHost(): SurfaceControlViewHost =
+ SurfaceControlViewHost(context, context.display, this, javaClass.simpleName)
+
+ fun relayout() {
+ spec.log("$tag relayout...")
+ viewHost?.run {
+ relayout(getWindowLayoutParams())
+ updateSurfacePosition()
+ }
+ }
+
+ protected fun updateSurfacePosition() {
+ spec.log("$tag updateSurfacePosition on layout $layout")
+ layout?.let {
+ updateSurfacePosition(
+ spec.layout.positionFactory(
+ it,
+ compatUIInfo,
+ state.sharedState,
+ state.stateForComponent(id)
+ )
+ )
+ }
+ }
+
+ protected fun getWindowLayoutParams(width: Int, height: Int): WindowManager.LayoutParams {
+ // Cannot be wrap_content as this determines the actual window size
+ val winParams =
+ WindowManager.LayoutParams(
+ width,
+ height,
+ WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+ spec.layout.layoutParamFlags,
+ PixelFormat.TRANSLUCENT
+ )
+ winParams.token = Binder()
+ winParams.title = javaClass.simpleName + compatUIInfo.taskInfo.taskId
+ winParams.privateFlags =
+ winParams.privateFlags or (WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
+ or WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY)
+ spec.log("$tag getWindowLayoutParams $winParams")
+ return winParams
+ }
+
+ /** Gets the layout params. */
+ protected fun getWindowLayoutParams(): WindowManager.LayoutParams =
+ layout?.run {
+ measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
+ spec.log(
+ "$tag getWindowLayoutParams size: ${measuredWidth}x$measuredHeight"
+ )
+ return getWindowLayoutParams(measuredWidth, measuredHeight)
+ } ?: WindowManager.LayoutParams()
+
+ protected fun updateSurfacePosition(position: Point) {
+ spec.log("$tag updateSurfacePosition on leash $leash")
+ leash?.run {
+ syncQueue.runInSync { t: SurfaceControl.Transaction ->
+ if (!isValid) {
+ spec.log("$tag The leash has been released.")
+ return@runInSync
+ }
+ spec.log("$tag settings position $position")
+ t.setPosition(this, position.x.toFloat(), position.y.toFloat())
+ }
+ }
+ }
+
+ private fun updateComponentState(
+ newInfo: CompatUIInfo,
+ componentState: CompatUIComponentState?
+ ) {
+ spec.log("$tag component state updating.... $componentState")
+ compatUIInfo = newInfo
+ }
+
+ private fun updateUI(state: CompatUIState) {
+ spec.log("$tag updating ui")
+ setConfiguration(compatUIInfo.taskInfo.configuration)
+ val componentState: CompatUIComponentState? = state.stateForComponent(id)
+ layout?.run {
+ spec.log("$tag viewBinder execution...")
+ spec.layout.viewBinder(this, compatUIInfo, state.sharedState, componentState)
+ relayout()
+ }
+ }
+
+ private fun initSurface(leash: SurfaceControl?) {
+ syncQueue.runInSync { t: SurfaceControl.Transaction ->
+ if (leash == null || !leash.isValid) {
+ spec.log("$tag The leash has been released.")
+ return@runInSync
+ }
+ t.setLayer(leash, spec.layout.zOrder)
+ }
}
-} \ No newline at end of file
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentFactory.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentFactory.kt
new file mode 100644
index 000000000000..55821ffdb6bd
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentFactory.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.compatui.api
+
+/**
+ * Abstracts the component responsible for the creation of a component
+ */
+interface CompatUIComponentFactory {
+
+ fun create(
+ spec: CompatUISpec,
+ compId: String,
+ state: CompatUIState,
+ compatUIInfo: CompatUIInfo,
+ ): CompatUIComponent
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentState.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentState.kt
index dcaea000d0a1..ec21924fbe16 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentState.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIComponentState.kt
@@ -18,7 +18,6 @@ package com.android.wm.shell.compatui.api
/**
* Abstraction of all the component specific state. Each
- * component can create its own state implementing this
- * tagging interface.
+ * component can create its own state implementing this interface.
*/
-interface CompatUIComponentState \ No newline at end of file
+interface CompatUIComponentState
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt
index 022906cf568c..de400f49d64b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUISpec.kt
@@ -16,6 +16,11 @@
package com.android.wm.shell.compatui.api
+import android.content.Context
+import android.graphics.Point
+import android.view.View
+import android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+import android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
import com.android.internal.protolog.ProtoLog
import com.android.wm.shell.protolog.ShellProtoLogGroup
@@ -39,6 +44,28 @@ class CompatUILifecyclePredicates(
)
/**
+ * Layout configuration
+ */
+data class CompatUILayout(
+ val zOrder: Int = 0,
+ val layoutParamFlags: Int = FLAG_NOT_FOCUSABLE or FLAG_NOT_TOUCH_MODAL,
+ val viewBuilder: (Context, CompatUIInfo, CompatUIComponentState?) -> View,
+ val viewBinder: (
+ View,
+ CompatUIInfo,
+ CompatUISharedState,
+ CompatUIComponentState?
+ ) -> Unit = { _, _, _, _ -> },
+ val positionFactory: (
+ View,
+ CompatUIInfo,
+ CompatUISharedState,
+ CompatUIComponentState?
+ ) -> Point,
+ val viewReleaser: () -> Unit = {}
+)
+
+/**
* Describes each compat ui component to the framework.
*/
class CompatUISpec(
@@ -47,5 +74,7 @@ class CompatUISpec(
// unique component identifier in the system.
val name: String,
// The lifecycle definition
- val lifecycle: CompatUILifecyclePredicates
+ val lifecycle: CompatUILifecyclePredicates,
+ // The layout definition
+ val layout: CompatUILayout
)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/components/RestartButtonSpec.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/components/RestartButtonSpec.kt
new file mode 100644
index 000000000000..e18cc0e5d416
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/components/RestartButtonSpec.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.compatui.components
+
+import android.annotation.SuppressLint
+import android.graphics.Point
+import android.view.LayoutInflater
+import android.view.View
+import android.window.TaskConstants
+import com.android.wm.shell.R
+import com.android.wm.shell.compatui.api.CompatUILayout
+import com.android.wm.shell.compatui.api.CompatUILifecyclePredicates
+import com.android.wm.shell.compatui.api.CompatUISpec
+
+/**
+ * CompatUISpec for the Restart Button
+ */
+@SuppressLint("InflateParams")
+val RestartButtonSpec = CompatUISpec(
+ name = "restartButton",
+ lifecycle = CompatUILifecyclePredicates(
+ creationPredicate = { info, _ ->
+ info.taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat
+ },
+ removalPredicate = { info, _, _ ->
+ !info.taskInfo.appCompatTaskInfo.isTopActivityInSizeCompat
+ }
+ ),
+ layout = CompatUILayout(
+ zOrder = TaskConstants.TASK_CHILD_LAYER_COMPAT_UI + 10,
+ viewBuilder = { ctx, _, _ ->
+ LayoutInflater.from(ctx).inflate(
+ R.layout.compat_ui_restart_button_layout,
+ null
+ )
+ },
+ viewBinder = { view, _, _, _ ->
+ view.visibility = View.VISIBLE
+ view.findViewById<View>(R.id.size_compat_restart_button)?.visibility = View.VISIBLE
+ },
+ // TODO(b/360288344): Calculate right position from stable bounds
+ positionFactory = { _, _, _, _ -> Point(500, 500) }
+ )
+)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIComponentFactory.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIComponentFactory.kt
new file mode 100644
index 000000000000..4eea6a31dd27
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIComponentFactory.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.compatui.impl
+
+import android.content.Context
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.compatui.api.CompatUIComponent
+import com.android.wm.shell.compatui.api.CompatUIComponentFactory
+import com.android.wm.shell.compatui.api.CompatUIInfo
+import com.android.wm.shell.compatui.api.CompatUISpec
+import com.android.wm.shell.compatui.api.CompatUIState
+
+/**
+ * Default {@link CompatUIComponentFactory } implementation
+ */
+class DefaultCompatUIComponentFactory(
+ private val context: Context,
+ private val syncQueue: SyncTransactionQueue,
+ private val displayController: DisplayController
+) : CompatUIComponentFactory {
+ override fun create(
+ spec: CompatUISpec,
+ compId: String,
+ state: CompatUIState,
+ compatUIInfo: CompatUIInfo
+ ): CompatUIComponent =
+ CompatUIComponent(
+ spec,
+ compId,
+ context,
+ state,
+ compatUIInfo,
+ syncQueue,
+ displayController.getDisplayLayout(compatUIInfo.taskInfo.displayId)
+ )
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt
index a7d1b4218a24..02db85a4f99d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt
@@ -16,7 +16,8 @@
package com.android.wm.shell.compatui.impl
-import com.android.wm.shell.compatui.api.CompatUIComponent
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.compatui.api.CompatUIComponentFactory
import com.android.wm.shell.compatui.api.CompatUIComponentIdGenerator
import com.android.wm.shell.compatui.api.CompatUIEvent
import com.android.wm.shell.compatui.api.CompatUIHandler
@@ -24,7 +25,6 @@ import com.android.wm.shell.compatui.api.CompatUIInfo
import com.android.wm.shell.compatui.api.CompatUIRepository
import com.android.wm.shell.compatui.api.CompatUIState
import java.util.function.Consumer
-import java.util.function.IntSupplier
/**
* Default implementation of {@link CompatUIHandler} to handle CompatUI components
@@ -32,7 +32,9 @@ import java.util.function.IntSupplier
class DefaultCompatUIHandler(
private val compatUIRepository: CompatUIRepository,
private val compatUIState: CompatUIState,
- private val componentIdGenerator: CompatUIComponentIdGenerator
+ private val componentIdGenerator: CompatUIComponentIdGenerator,
+ private val componentFactory: CompatUIComponentFactory,
+ private val executor: ShellExecutor
) : CompatUIHandler {
private var compatUIEventSender: Consumer<CompatUIEvent>? = null
@@ -41,23 +43,36 @@ class DefaultCompatUIHandler(
compatUIRepository.iterateOn { spec ->
// We get the identifier for the component depending on the task and spec
val componentId = componentIdGenerator.generateId(compatUIInfo, spec)
- // We check in the state if the component already exists
- var comp = compatUIState.getUIComponent(componentId)
- if (comp == null) {
+ spec.log("Evaluating component $componentId")
+ // We check in the state if the component does not yet exist
+ var component = compatUIState.getUIComponent(componentId)
+ if (component == null) {
+ spec.log("Component $componentId not present")
// We evaluate the predicate
if (spec.lifecycle.creationPredicate(compatUIInfo, compatUIState.sharedState)) {
+ spec.log("Component $componentId should be created")
// We create the component and store in the
// global state
- comp = CompatUIComponent(spec, componentId)
+ component =
+ componentFactory.create(spec, componentId, compatUIState, compatUIInfo)
+ spec.log("Component $componentId created $component")
// We initialize the state for the component
val compState = spec.lifecycle.stateBuilder(
compatUIInfo,
compatUIState.sharedState
)
- compatUIState.registerUIComponent(componentId, comp, compState)
+ spec.log("Component $componentId initial state $compState")
+ compatUIState.registerUIComponent(componentId, component, compState)
+ spec.log("Component $componentId registered")
+ // We initialize the layout for the component
+ component.initLayout(compatUIInfo)
+ spec.log("Component $componentId layout created")
// Now we can invoke the update passing the shared state and
// the state specific to the component
- comp.update(compatUIInfo, compatUIState)
+ executor.execute {
+ component.update(compatUIInfo)
+ spec.log("Component $componentId updated with $compatUIInfo")
+ }
}
} else {
// The component is present. We check if we need to remove it
@@ -66,13 +81,18 @@ class DefaultCompatUIHandler(
compatUIState.sharedState,
compatUIState.stateForComponent(componentId)
)) {
+ spec.log("Component $componentId should be removed")
// We clean the component
- comp.release()
- // We remove the component
+ component.release()
+ spec.log("Component $componentId released")
compatUIState.unregisterUIComponent(componentId)
+ spec.log("Component $componentId removed from registry")
} else {
- // The component exists so we need to invoke the update methods
- comp.update(compatUIInfo, compatUIState)
+ executor.execute {
+ // The component exists so we need to invoke the update methods
+ component.update(compatUIInfo)
+ spec.log("Component $componentId updated with $compatUIInfo")
+ }
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 52ff0147d996..98536bf98f0b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -76,10 +76,13 @@ import com.android.wm.shell.compatui.CompatUIConfiguration;
import com.android.wm.shell.compatui.CompatUIController;
import com.android.wm.shell.compatui.CompatUIShellCommandHandler;
import com.android.wm.shell.compatui.CompatUIStatusManager;
+import com.android.wm.shell.compatui.api.CompatUIComponentFactory;
import com.android.wm.shell.compatui.api.CompatUIComponentIdGenerator;
import com.android.wm.shell.compatui.api.CompatUIHandler;
import com.android.wm.shell.compatui.api.CompatUIRepository;
import com.android.wm.shell.compatui.api.CompatUIState;
+import com.android.wm.shell.compatui.components.RestartButtonSpecKt;
+import com.android.wm.shell.compatui.impl.DefaultCompatUIComponentFactory;
import com.android.wm.shell.compatui.impl.DefaultCompatUIHandler;
import com.android.wm.shell.compatui.impl.DefaultCompatUIRepository;
import com.android.wm.shell.compatui.impl.DefaultComponentIdGenerator;
@@ -260,13 +263,15 @@ public abstract class WMShellBaseModule {
CompatUIRepository compatUIRepository,
@NonNull CompatUIState compatUIState,
@NonNull CompatUIComponentIdGenerator componentIdGenerator,
+ @NonNull CompatUIComponentFactory compatUIComponentFactory,
CompatUIStatusManager compatUIStatusManager) {
if (!context.getResources().getBoolean(R.bool.config_enableCompatUIController)) {
return Optional.empty();
}
if (Flags.appCompatUiFramework()) {
- return Optional.of(new DefaultCompatUIHandler(compatUIRepository, compatUIState,
- componentIdGenerator));
+ return Optional.of(
+ new DefaultCompatUIHandler(compatUIRepository, compatUIState,
+ componentIdGenerator, compatUIComponentFactory, mainExecutor));
}
return Optional.of(
new CompatUIController(
@@ -308,6 +313,15 @@ public abstract class WMShellBaseModule {
@WMSingleton
@Provides
+ static CompatUIComponentFactory provideCompatUIComponentFactory(
+ @NonNull Context context,
+ @NonNull SyncTransactionQueue syncQueue,
+ @NonNull DisplayController displayController) {
+ return new DefaultCompatUIComponentFactory(context, syncQueue, displayController);
+ }
+
+ @WMSingleton
+ @Provides
static CompatUIComponentIdGenerator provideCompatUIComponentIdGenerator() {
return new DefaultComponentIdGenerator();
}
@@ -315,7 +329,10 @@ public abstract class WMShellBaseModule {
@WMSingleton
@Provides
static CompatUIRepository provideCompatUIRepository() {
- return new DefaultCompatUIRepository();
+ // TODO(b/360288344) Integrate Dagger Multibinding
+ final CompatUIRepository repository = new DefaultCompatUIRepository();
+ repository.addSpec(RestartButtonSpecKt.getRestartButtonSpec());
+ return repository;
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 2f506434ba90..ce054a833107 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -59,6 +59,7 @@ import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.dagger.back.ShellBackAnimationModule;
import com.android.wm.shell.dagger.pip.PipModule;
import com.android.wm.shell.desktopmode.DefaultDragToDesktopTransitionHandler;
+import com.android.wm.shell.desktopmode.DesktopModeDragAndDropTransitionHandler;
import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.desktopmode.DesktopModeLoggerTransitionObserver;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
@@ -303,6 +304,7 @@ public abstract class WMShellModule {
ShellInit shellInit,
ShellTaskOrganizer shellTaskOrganizer,
Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
+ LaunchAdjacentController launchAdjacentController,
WindowDecorViewModel windowDecorViewModel) {
// TODO(b/238217847): Temporarily add this check here until we can remove the dynamic
// override for this controller from the base module
@@ -310,7 +312,7 @@ public abstract class WMShellModule {
? shellInit
: null;
return new FreeformTaskListener(context, init, shellTaskOrganizer,
- desktopModeTaskRepository, windowDecorViewModel);
+ desktopModeTaskRepository, launchAdjacentController, windowDecorViewModel);
}
@WMSingleton
@@ -558,6 +560,7 @@ public abstract class WMShellModule {
ReturnToDragStartAnimator returnToDragStartAnimator,
EnterDesktopTaskTransitionHandler enterDesktopTransitionHandler,
ExitDesktopTaskTransitionHandler exitDesktopTransitionHandler,
+ DesktopModeDragAndDropTransitionHandler desktopModeDragAndDropTransitionHandler,
ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
DragToDesktopTransitionHandler dragToDesktopTransitionHandler,
@DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository,
@@ -573,7 +576,8 @@ public abstract class WMShellModule {
displayController, shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer,
dragAndDropController, transitions, keyguardManager,
returnToDragStartAnimator, enterDesktopTransitionHandler,
- exitDesktopTransitionHandler, toggleResizeDesktopTaskTransitionHandler,
+ exitDesktopTransitionHandler, desktopModeDragAndDropTransitionHandler,
+ toggleResizeDesktopTaskTransitionHandler,
dragToDesktopTransitionHandler, desktopModeTaskRepository,
desktopModeLoggerTransitionObserver, launchAdjacentController,
recentsTransitionHandler, multiInstanceHelper, mainExecutor, desktopTasksLimiter,
@@ -655,6 +659,14 @@ public abstract class WMShellModule {
@WMSingleton
@Provides
+ static DesktopModeDragAndDropTransitionHandler provideDesktopModeDragAndDropTransitionHandler(
+ Transitions transitions
+ ) {
+ return new DesktopModeDragAndDropTransitionHandler(transitions);
+ }
+
+ @WMSingleton
+ @Provides
@DynamicOverride
static DesktopModeTaskRepository provideDesktopModeTaskRepository() {
return new DesktopModeTaskRepository();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeDragAndDropTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeDragAndDropTransitionHandler.kt
new file mode 100644
index 000000000000..a7a4a1036b5d
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeDragAndDropTransitionHandler.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.desktopmode
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ValueAnimator
+import android.os.IBinder
+import android.view.SurfaceControl
+import android.view.WindowManager.TRANSIT_OPEN
+import android.window.TransitionInfo
+import android.window.TransitionRequestInfo
+import android.window.WindowContainerTransaction
+import com.android.wm.shell.transition.Transitions
+import com.android.wm.shell.transition.Transitions.TransitionFinishCallback
+
+/**
+ * Transition handler for drag-and-drop (i.e., tab tear) transitions that occur in desktop mode.
+ */
+class DesktopModeDragAndDropTransitionHandler(private val transitions: Transitions) :
+ Transitions.TransitionHandler {
+ private val pendingTransitionTokens: MutableList<IBinder> = mutableListOf()
+
+ /**
+ * Begin a transition when a [android.app.PendingIntent] is dropped without a window to
+ * accept it.
+ */
+ fun handleDropEvent(wct: WindowContainerTransaction): IBinder {
+ val token = transitions.startTransition(TRANSIT_OPEN, wct, this)
+ pendingTransitionTokens.add(token)
+ return token
+ }
+
+ override fun startAnimation(
+ transition: IBinder,
+ info: TransitionInfo,
+ startTransaction: SurfaceControl.Transaction,
+ finishTransaction: SurfaceControl.Transaction,
+ finishCallback: TransitionFinishCallback
+ ): Boolean {
+ if (!pendingTransitionTokens.contains(transition)) return false
+ val change = findRelevantChange(info)
+ val leash = change.leash
+ val endBounds = change.endAbsBounds
+ startTransaction.hide(leash)
+ .setWindowCrop(leash, endBounds.width(), endBounds.height())
+ .apply()
+ val animator = ValueAnimator()
+ animator.setFloatValues(0f, 1f)
+ animator.setDuration(FADE_IN_ANIMATION_DURATION)
+ val t = SurfaceControl.Transaction()
+ animator.addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationStart(animation: Animator) {
+ t.show(leash)
+ t.apply()
+ }
+
+ override fun onAnimationEnd(animation: Animator) {
+ finishCallback.onTransitionFinished(null)
+ }
+ })
+ animator.addUpdateListener { animation: ValueAnimator ->
+ t.setAlpha(leash, animation.animatedFraction)
+ t.apply()
+ }
+ animator.start()
+ pendingTransitionTokens.remove(transition)
+ return true
+ }
+
+ private fun findRelevantChange(info: TransitionInfo): TransitionInfo.Change {
+ val matchingChanges =
+ info.changes.filter { c ->
+ isValidTaskChange(c) && c.mode == TRANSIT_OPEN
+ }
+ if (matchingChanges.size != 1) {
+ throw IllegalStateException(
+ "Expected 1 relevant change but found: ${matchingChanges.size}"
+ )
+ }
+ return matchingChanges.first()
+ }
+
+ private fun isValidTaskChange(change: TransitionInfo.Change): Boolean {
+ return change.taskInfo != null && change.taskInfo?.taskId != -1
+ }
+
+ override fun handleRequest(
+ transition: IBinder,
+ request: TransitionRequestInfo
+ ): WindowContainerTransaction? {
+ return null
+ }
+
+ companion object {
+ const val FADE_IN_ANIMATION_DURATION = 300L
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 09f9139cb1d5..bfc0ee803591 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -16,7 +16,6 @@
package com.android.wm.shell.desktopmode;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -29,7 +28,6 @@ import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
-import android.app.WindowConfiguration;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.PixelFormat;
@@ -70,6 +68,37 @@ public class DesktopModeVisualIndicator {
TO_SPLIT_RIGHT_INDICATOR
}
+ /**
+ * The conditions surrounding the drag event that led to the indicator's creation.
+ */
+ public enum DragStartState {
+ /** The indicator is resulting from a freeform task drag. */
+ FROM_FREEFORM,
+ /** The indicator is resulting from a split screen task drag */
+ FROM_SPLIT,
+ /** The indicator is resulting from a fullscreen task drag */
+ FROM_FULLSCREEN,
+ /** The indicator is resulting from an Intent generated during a drag-and-drop event */
+ DRAGGED_INTENT;
+
+ /**
+ * Get the {@link DragStartState} of a drag event based on the windowing mode of the task.
+ * Note that DRAGGED_INTENT will be specified by the caller if needed and not returned
+ * here.
+ */
+ public static DesktopModeVisualIndicator.DragStartState getDragStartState(
+ ActivityManager.RunningTaskInfo taskInfo
+ ) {
+ if (taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
+ return FROM_FULLSCREEN;
+ } else if (taskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW) {
+ return FROM_SPLIT;
+ } else if (taskInfo.isFreeform()) {
+ return FROM_FREEFORM;
+ } else return null;
+ }
+ }
+
private final Context mContext;
private final DisplayController mDisplayController;
private final RootTaskDisplayAreaOrganizer mRootTdaOrganizer;
@@ -82,11 +111,13 @@ public class DesktopModeVisualIndicator {
private View mView;
private IndicatorType mCurrentType;
+ private DragStartState mDragStartState;
public DesktopModeVisualIndicator(SyncTransactionQueue syncQueue,
ActivityManager.RunningTaskInfo taskInfo, DisplayController displayController,
Context context, SurfaceControl taskSurface,
- RootTaskDisplayAreaOrganizer taskDisplayAreaOrganizer) {
+ RootTaskDisplayAreaOrganizer taskDisplayAreaOrganizer,
+ DragStartState dragStartState) {
mSyncQueue = syncQueue;
mTaskInfo = taskInfo;
mDisplayController = displayController;
@@ -94,6 +125,7 @@ public class DesktopModeVisualIndicator {
mTaskSurface = taskSurface;
mRootTdaOrganizer = taskDisplayAreaOrganizer;
mCurrentType = IndicatorType.NO_INDICATOR;
+ mDragStartState = dragStartState;
}
/**
@@ -101,7 +133,7 @@ public class DesktopModeVisualIndicator {
* display, including no visible indicator.
*/
@NonNull
- IndicatorType updateIndicatorType(PointF inputCoordinates, int windowingMode) {
+ IndicatorType updateIndicatorType(PointF inputCoordinates) {
final DisplayLayout layout = mDisplayController.getDisplayLayout(mTaskInfo.displayId);
// If we are in freeform, we don't want a visible indicator in the "freeform" drag zone.
IndicatorType result = IndicatorType.NO_INDICATOR;
@@ -111,14 +143,13 @@ public class DesktopModeVisualIndicator {
// account for the possibility of the task going off the top of the screen by captionHeight
final int captionHeight = mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.desktop_mode_freeform_decor_caption_height);
- final Region fullscreenRegion = calculateFullscreenRegion(layout, windowingMode,
+ final Region fullscreenRegion = calculateFullscreenRegion(layout, captionHeight);
+ final Region splitLeftRegion = calculateSplitLeftRegion(layout, transitionAreaWidth,
captionHeight);
- final Region splitLeftRegion = calculateSplitLeftRegion(layout, windowingMode,
- transitionAreaWidth, captionHeight);
- final Region splitRightRegion = calculateSplitRightRegion(layout, windowingMode,
- transitionAreaWidth, captionHeight);
- final Region toDesktopRegion = calculateToDesktopRegion(layout, windowingMode,
- splitLeftRegion, splitRightRegion, fullscreenRegion);
+ final Region splitRightRegion = calculateSplitRightRegion(layout, transitionAreaWidth,
+ captionHeight);
+ final Region toDesktopRegion = calculateToDesktopRegion(layout, splitLeftRegion,
+ splitRightRegion, fullscreenRegion);
if (fullscreenRegion.contains((int) inputCoordinates.x, (int) inputCoordinates.y)) {
result = IndicatorType.TO_FULLSCREEN_INDICATOR;
}
@@ -131,20 +162,22 @@ public class DesktopModeVisualIndicator {
if (toDesktopRegion.contains((int) inputCoordinates.x, (int) inputCoordinates.y)) {
result = IndicatorType.TO_DESKTOP_INDICATOR;
}
- transitionIndicator(result);
+ if (mDragStartState != DragStartState.DRAGGED_INTENT) {
+ transitionIndicator(result);
+ }
return result;
}
@VisibleForTesting
- Region calculateFullscreenRegion(DisplayLayout layout,
- @WindowConfiguration.WindowingMode int windowingMode, int captionHeight) {
+ Region calculateFullscreenRegion(DisplayLayout layout, int captionHeight) {
final Region region = new Region();
- int transitionHeight = windowingMode == WINDOWING_MODE_FREEFORM
+ int transitionHeight = mDragStartState == DragStartState.FROM_FREEFORM
+ || mDragStartState == DragStartState.DRAGGED_INTENT
? mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.desktop_mode_transition_region_thickness)
: 2 * layout.stableInsets().top;
// A Rect at the top of the screen that takes up the center 40%.
- if (windowingMode == WINDOWING_MODE_FREEFORM) {
+ if (mDragStartState == DragStartState.FROM_FREEFORM) {
final float toFullscreenScale = mContext.getResources().getFloat(
R.dimen.desktop_mode_fullscreen_region_scale);
final float toFullscreenWidth = (layout.width() * toFullscreenScale);
@@ -153,9 +186,11 @@ public class DesktopModeVisualIndicator {
(int) ((layout.width() / 2f) + (toFullscreenWidth / 2f)),
transitionHeight));
}
- // A screen-wide Rect if the task is in fullscreen or split.
- if (windowingMode == WINDOWING_MODE_FULLSCREEN
- || windowingMode == WINDOWING_MODE_MULTI_WINDOW) {
+ // A screen-wide Rect if the task is in fullscreen, split, or a dragged intent.
+ if (mDragStartState == DragStartState.FROM_FULLSCREEN
+ || mDragStartState == DragStartState.FROM_SPLIT
+ || mDragStartState == DragStartState.DRAGGED_INTENT
+ ) {
region.union(new Rect(0,
-captionHeight,
layout.width(),
@@ -166,12 +201,11 @@ public class DesktopModeVisualIndicator {
@VisibleForTesting
Region calculateToDesktopRegion(DisplayLayout layout,
- @WindowConfiguration.WindowingMode int windowingMode,
Region splitLeftRegion, Region splitRightRegion,
Region toFullscreenRegion) {
final Region region = new Region();
// If in desktop, we need no region. Otherwise it's the same for all windowing modes.
- if (windowingMode != WINDOWING_MODE_FREEFORM) {
+ if (mDragStartState != DragStartState.FROM_FREEFORM) {
region.union(new Rect(0, 0, layout.width(), layout.height()));
region.op(splitLeftRegion, Region.Op.DIFFERENCE);
region.op(splitRightRegion, Region.Op.DIFFERENCE);
@@ -182,11 +216,10 @@ public class DesktopModeVisualIndicator {
@VisibleForTesting
Region calculateSplitLeftRegion(DisplayLayout layout,
- @WindowConfiguration.WindowingMode int windowingMode,
int transitionEdgeWidth, int captionHeight) {
final Region region = new Region();
// In freeform, keep the top corners clear.
- int transitionHeight = windowingMode == WINDOWING_MODE_FREEFORM
+ int transitionHeight = mDragStartState == DragStartState.FROM_FREEFORM
? mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.desktop_mode_split_from_desktop_height) :
-captionHeight;
@@ -196,11 +229,10 @@ public class DesktopModeVisualIndicator {
@VisibleForTesting
Region calculateSplitRightRegion(DisplayLayout layout,
- @WindowConfiguration.WindowingMode int windowingMode,
int transitionEdgeWidth, int captionHeight) {
final Region region = new Region();
// In freeform, keep the top corners clear.
- int transitionHeight = windowingMode == WINDOWING_MODE_FREEFORM
+ int transitionHeight = mDragStartState == DragStartState.FROM_FREEFORM
? mContext.getResources().getDimensionPixelSize(
com.android.wm.shell.R.dimen.desktop_mode_split_from_desktop_height) :
-captionHeight;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 0cf0345f024d..33794d242c03 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -34,10 +34,12 @@ import android.graphics.Point
import android.graphics.PointF
import android.graphics.Rect
import android.graphics.Region
+import android.os.Binder
import android.os.IBinder
import android.os.SystemProperties
import android.util.Size
import android.view.Display.DEFAULT_DISPLAY
+import android.view.DragEvent
import android.view.SurfaceControl
import android.view.WindowManager.TRANSIT_CHANGE
import android.view.WindowManager.TRANSIT_NONE
@@ -69,6 +71,7 @@ import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource
import com.android.wm.shell.compatui.isTopActivityExemptFromDesktopWindowing
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
+import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.DragStartState
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.DragToDesktopStateListener
import com.android.wm.shell.draganddrop.DragAndDropController
@@ -121,6 +124,7 @@ class DesktopTasksController(
private val returnToDragStartAnimator: ReturnToDragStartAnimator,
private val enterDesktopTaskTransitionHandler: EnterDesktopTaskTransitionHandler,
private val exitDesktopTaskTransitionHandler: ExitDesktopTaskTransitionHandler,
+ private val desktopModeDragAndDropTransitionHandler: DesktopModeDragAndDropTransitionHandler,
private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
private val dragToDesktopTransitionHandler: DragToDesktopTransitionHandler,
private val taskRepository: DesktopModeTaskRepository,
@@ -146,12 +150,6 @@ class DesktopTasksController(
visualIndicator?.releaseVisualIndicator(t)
visualIndicator = null
}
- private val taskVisibilityListener =
- object : VisibleTasksListener {
- override fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {
- launchAdjacentController.launchAdjacentEnabled = visibleTasksCount == 0
- }
- }
private val dragToDesktopStateListener =
object : DragToDesktopStateListener {
override fun onCommitToDesktopAnimationStart(tx: SurfaceControl.Transaction) {
@@ -176,6 +174,9 @@ class DesktopTasksController(
private var recentsAnimationRunning = false
private lateinit var splitScreenController: SplitScreenController
+ // Launch cookie used to identify a drag and drop transition to fullscreen after it has begun.
+ // Used to prevent handleRequest from moving the new fullscreen task to freeform.
+ private var dragAndDropFullscreenCookie: Binder? = null
init {
desktopMode = DesktopModeImpl()
@@ -194,7 +195,6 @@ class DesktopTasksController(
this
)
transitions.addHandler(this)
- taskRepository.addVisibleTasksListener(taskVisibilityListener, mainExecutor)
dragToDesktopTransitionHandler.dragToDesktopStateListener = dragToDesktopStateListener
recentsTransitionHandler.addTransitionStateListener(
object : RecentsTransitionStateListener {
@@ -858,6 +858,7 @@ class DesktopTasksController(
val triggerTask = request.triggerTask
var shouldHandleMidRecentsFreeformLaunch =
recentsAnimationRunning && isFreeformRelaunch(triggerTask, request)
+ val isDragAndDropFullscreenTransition = taskContainsDragAndDropCookie(triggerTask)
val shouldHandleRequest =
when {
// Handle freeform relaunch during recents animation
@@ -866,6 +867,13 @@ class DesktopTasksController(
reason = "recents animation is running"
false
}
+ // Don't handle request if this was a tear to fullscreen transition.
+ // handleFullscreenTaskLaunch moves fullscreen intents to freeform;
+ // this is an exception to the rule
+ isDragAndDropFullscreenTransition -> {
+ dragAndDropFullscreenCookie = null
+ false
+ }
// Handle task closing for the last window if wallpaper is available
shouldHandleTaskClosing(request) -> true
// Only handle open or to front transitions
@@ -884,8 +892,7 @@ class DesktopTasksController(
false
}
// Only handle fullscreen or freeform tasks
- triggerTask.windowingMode != WINDOWING_MODE_FULLSCREEN &&
- triggerTask.windowingMode != WINDOWING_MODE_FREEFORM -> {
+ !triggerTask.isFullscreen && !triggerTask.isFreeform -> {
reason = "windowingMode not handled (${triggerTask.windowingMode})"
false
}
@@ -920,6 +927,9 @@ class DesktopTasksController(
return result
}
+ private fun taskContainsDragAndDropCookie(taskInfo: RunningTaskInfo?) =
+ taskInfo?.launchCookies?.any { it == dragAndDropFullscreenCookie } ?: false
+
/**
* Applies the proper surface states (rounded corners) to tasks when desktop mode is active.
* This is intended to be used when desktop mode is part of another animation but isn't, itself,
@@ -1319,15 +1329,17 @@ class DesktopTasksController(
taskBounds: Rect
) {
if (taskInfo.windowingMode != WINDOWING_MODE_FREEFORM) return
- updateVisualIndicator(taskInfo, taskSurface, inputX, taskBounds.top.toFloat())
+ updateVisualIndicator(taskInfo, taskSurface, inputX, taskBounds.top.toFloat(),
+ DragStartState.FROM_FREEFORM)
}
fun updateVisualIndicator(
taskInfo: RunningTaskInfo,
- taskSurface: SurfaceControl,
+ taskSurface: SurfaceControl?,
inputX: Float,
- taskTop: Float
- ): IndicatorType {
+ taskTop: Float,
+ dragStartState: DragStartState
+ ): DesktopModeVisualIndicator.IndicatorType {
// If the visual indicator does not exist, create it.
val indicator =
visualIndicator
@@ -1337,10 +1349,11 @@ class DesktopTasksController(
displayController,
context,
taskSurface,
- rootTaskDisplayAreaOrganizer
+ rootTaskDisplayAreaOrganizer,
+ dragStartState
)
if (visualIndicator == null) visualIndicator = indicator
- return indicator.updateIndicatorType(PointF(inputX, taskTop), taskInfo.windowingMode)
+ return indicator.updateIndicatorType(PointF(inputX, taskTop))
}
/**
@@ -1373,7 +1386,6 @@ class DesktopTasksController(
val indicatorType =
indicator.updateIndicatorType(
PointF(inputCoordinate.x, currentDragBounds.top.toFloat()),
- taskInfo.windowingMode
)
when (indicatorType) {
IndicatorType.TO_FULLSCREEN_INDICATOR -> {
@@ -1434,7 +1446,7 @@ class DesktopTasksController(
// End the drag_hold CUJ interaction.
interactionJankMonitor.end(CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_HOLD)
val indicator = getVisualIndicator() ?: return IndicatorType.NO_INDICATOR
- val indicatorType = indicator.updateIndicatorType(inputCoordinates, taskInfo.windowingMode)
+ val indicatorType = indicator.updateIndicatorType(inputCoordinates)
when (indicatorType) {
IndicatorType.TO_DESKTOP_INDICATOR -> {
// Start a new jank interaction for the drag release to desktop window animation.
@@ -1486,9 +1498,10 @@ class DesktopTasksController(
taskRepository.setExclusionRegionListener(listener, callbackExecutor)
}
+ // TODO(b/358114479): Move this implementation into a separate class.
override fun onUnhandledDrag(
launchIntent: PendingIntent,
- dragSurface: SurfaceControl,
+ dragEvent: DragEvent,
onFinishCallback: Consumer<Boolean>
): Boolean {
// TODO(b/320797628): Pass through which display we are dropping onto
@@ -1496,7 +1509,6 @@ class DesktopTasksController(
// Not currently in desktop mode, ignore the drop
return false
}
-
val launchComponent = getComponent(launchIntent)
if (!multiInstanceHelper.supportsMultiInstanceSplit(launchComponent)) {
// TODO(b/320797628): Should only return early if there is an existing running task, and
@@ -1504,20 +1516,69 @@ class DesktopTasksController(
logV("Dropped intent does not support multi-instance")
return false
}
-
+ val taskInfo = getFocusedFreeformTask(DEFAULT_DISPLAY) ?: return false
+ // TODO(b/358114479): Update drag and drop handling to give us visibility into when another
+ // window will accept a drag event. This way, we can hide the indicator when we won't
+ // be handling the transition here, allowing us to display the indicator accurately.
+ // For now, we create the indicator only on drag end and immediately dispose it.
+ val indicatorType = updateVisualIndicator(taskInfo, dragEvent.dragSurface,
+ dragEvent.x, dragEvent.y,
+ DragStartState.DRAGGED_INTENT)
+ releaseVisualIndicator()
+ val windowingMode = when (indicatorType) {
+ IndicatorType.TO_FULLSCREEN_INDICATOR -> {
+ WINDOWING_MODE_FULLSCREEN
+ }
+ IndicatorType.TO_SPLIT_LEFT_INDICATOR,
+ IndicatorType.TO_SPLIT_RIGHT_INDICATOR,
+ IndicatorType.TO_DESKTOP_INDICATOR
+ -> {
+ WINDOWING_MODE_FREEFORM
+ }
+ else -> error("Invalid indicator type: $indicatorType")
+ }
+ val displayLayout = displayController.getDisplayLayout(DEFAULT_DISPLAY) ?: return false
+ val newWindowBounds = Rect()
+ when (indicatorType) {
+ IndicatorType.TO_DESKTOP_INDICATOR -> {
+ // Use default bounds, but with the top-center at the drop point.
+ newWindowBounds.set(getDefaultDesktopTaskBounds(displayLayout))
+ newWindowBounds.offsetTo(
+ dragEvent.x.toInt() - (newWindowBounds.width() / 2),
+ dragEvent.y.toInt()
+ )
+ }
+ IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+ newWindowBounds.set(getSnapBounds(taskInfo, SnapPosition.RIGHT))
+ }
+ IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+ newWindowBounds.set(getSnapBounds(taskInfo, SnapPosition.LEFT))
+ }
+ else -> {
+ // Use empty bounds for the fullscreen case.
+ }
+ }
// Start a new transition to launch the app
val opts =
ActivityOptions.makeBasic().apply {
- launchWindowingMode = WINDOWING_MODE_FREEFORM
+ launchWindowingMode = windowingMode
+ launchBounds = newWindowBounds
+ pendingIntentBackgroundActivityStartMode =
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS
pendingIntentLaunchFlags =
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK
- setPendingIntentBackgroundActivityStartMode(
- ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED
- )
}
+ if (windowingMode == WINDOWING_MODE_FULLSCREEN) {
+ dragAndDropFullscreenCookie = Binder()
+ opts.launchCookie = dragAndDropFullscreenCookie
+ }
val wct = WindowContainerTransaction()
wct.sendPendingIntent(launchIntent, null, opts.toBundle())
- transitions.startTransition(TRANSIT_OPEN, wct, null /* handler */)
+ if (windowingMode == WINDOWING_MODE_FREEFORM) {
+ desktopModeDragAndDropTransitionHandler.handleDropEvent(wct)
+ } else {
+ transitions.startTransition(TRANSIT_OPEN, wct, null)
+ }
// Report that this is handled by the listener
onFinishCallback.accept(true)
@@ -1525,7 +1586,7 @@ class DesktopTasksController(
// We've assumed responsibility of cleaning up the drag surface, so do that now
// TODO(b/320797628): Do an actual animation here for the drag surface
val t = SurfaceControl.Transaction()
- t.remove(dragSurface)
+ t.remove(dragEvent.dragSurface)
t.apply()
return true
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
index 6cc10ea92bb4..cf02fb5fde8e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
@@ -70,6 +70,7 @@ import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.annotations.ExternalMainThread;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
@@ -127,7 +128,7 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
* drag.
*/
default boolean onUnhandledDrag(@NonNull PendingIntent launchIntent,
- @NonNull SurfaceControl dragSurface,
+ @NonNull DragEvent dragEvent,
@NonNull Consumer<Boolean> onFinishCallback) {
return false;
}
@@ -329,9 +330,18 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
return false;
}
+ DragSession dragSession = null;
if (event.getAction() == ACTION_DRAG_STARTED) {
mActiveDragDisplay = displayId;
- pd.isHandlingDrag = DragUtils.canHandleDrag(event);
+ dragSession = new DragSession(ActivityTaskManager.getInstance(),
+ mDisplayController.getDisplayLayout(displayId), event.getClipData(),
+ event.getDragFlags());
+ dragSession.initialize();
+ final ActivityManager.RunningTaskInfo taskInfo = dragSession.runningTaskInfo;
+ // Desktop tasks will have their own drag handling.
+ final boolean isDesktopDrag = taskInfo != null && taskInfo.isFreeform()
+ && DesktopModeStatus.canEnterDesktopMode(mContext);
+ pd.isHandlingDrag = DragUtils.canHandleDrag(event) && !isDesktopDrag;
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
"Clip description: handlingDrag=%b itemCount=%d mimeTypes=%s flags=%s",
pd.isHandlingDrag, event.getClipData().getItemCount(),
@@ -349,10 +359,7 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
Slog.w(TAG, "Unexpected drag start during an active drag");
return false;
}
- pd.dragSession = new DragSession(ActivityTaskManager.getInstance(),
- mDisplayController.getDisplayLayout(displayId), event.getClipData(),
- event.getDragFlags());
- pd.dragSession.initialize();
+ pd.dragSession = dragSession;
pd.activeDragCount++;
pd.dragLayout.prepare(pd.dragSession, mLogger.logStart(pd.dragSession));
if (pd.dragSession.hideDragSourceTaskId != -1) {
@@ -437,7 +444,7 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll
}
final boolean handled = notifyListeners(
- l -> l.onUnhandledDrag(launchIntent, dragEvent.getDragSurface(), onFinishCallback));
+ l -> l.onUnhandledDrag(launchIntent, dragEvent, onFinishCallback));
if (!handled) {
// Nobody handled this, we still have to notify WM
onFinishCallback.accept(false);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 456767a1c9af..83cc18baf6cc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -27,6 +27,7 @@ import android.view.SurfaceControl;
import com.android.internal.protolog.ProtoLog;
import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.LaunchAdjacentController;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -49,6 +50,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
private final ShellTaskOrganizer mShellTaskOrganizer;
private final Optional<DesktopModeTaskRepository> mDesktopModeTaskRepository;
private final WindowDecorViewModel mWindowDecorationViewModel;
+ private final LaunchAdjacentController mLaunchAdjacentController;
private final SparseArray<State> mTasks = new SparseArray<>();
@@ -62,11 +64,13 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
ShellInit shellInit,
ShellTaskOrganizer shellTaskOrganizer,
Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
+ LaunchAdjacentController launchAdjacentController,
WindowDecorViewModel windowDecorationViewModel) {
mContext = context;
mShellTaskOrganizer = shellTaskOrganizer;
mWindowDecorationViewModel = windowDecorationViewModel;
mDesktopModeTaskRepository = desktopModeTaskRepository;
+ mLaunchAdjacentController = launchAdjacentController;
if (shellInit != null) {
shellInit.addInitCallback(this::onInit, this);
}
@@ -106,6 +110,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
}
});
}
+ updateLaunchAdjacentController();
}
@Override
@@ -123,6 +128,7 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
mWindowDecorationViewModel.destroyWindowDecoration(taskInfo);
}
+ updateLaunchAdjacentController();
}
@Override
@@ -144,6 +150,17 @@ public class FreeformTaskListener implements ShellTaskOrganizer.TaskListener,
taskInfo.isVisible);
});
}
+ updateLaunchAdjacentController();
+ }
+
+ private void updateLaunchAdjacentController() {
+ for (int i = 0; i < mTasks.size(); i++) {
+ if (mTasks.valueAt(i).mTaskInfo.isVisible) {
+ mLaunchAdjacentController.setLaunchAdjacentEnabled(false);
+ return;
+ }
+ }
+ mLaunchAdjacentController.setLaunchAdjacentEnabled(true);
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
index 287e779d8e24..1140c82a7a08 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
@@ -48,7 +48,7 @@ public class ShellInit {
public ShellInit(ShellExecutor mainExecutor) {
mMainExecutor = mainExecutor;
- ProtoLog.registerGroups(ShellProtoLogGroup.values());
+ ProtoLog.init(ShellProtoLogGroup.values());
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 12b47cf5e7d6..457b5112076e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -1031,7 +1031,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
}
final boolean shouldStartTransitionDrag =
relevantDecor.checkTouchEventInFocusedCaptionHandle(ev)
- || Flags.enableAdditionalWindowsAboveStatusBar();
+ || Flags.enableAdditionalWindowsAboveStatusBar();
if (dragFromStatusBarAllowed && shouldStartTransitionDrag) {
mTransitionDragActive = true;
}
@@ -1039,8 +1039,13 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
}
case MotionEvent.ACTION_UP: {
if (mTransitionDragActive) {
+ final DesktopModeVisualIndicator.DragStartState dragStartState =
+ DesktopModeVisualIndicator.DragStartState
+ .getDragStartState(relevantDecor.mTaskInfo);
+ if (dragStartState == null) return;
mDesktopTasksController.updateVisualIndicator(relevantDecor.mTaskInfo,
- relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY());
+ relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY(),
+ dragStartState);
mTransitionDragActive = false;
if (mMoveToDesktopAnimator != null) {
// Though this isn't a hover event, we need to update handle's hover state
@@ -1080,10 +1085,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
&& mMoveToDesktopAnimator == null) {
return;
}
+ final DesktopModeVisualIndicator.DragStartState dragStartState =
+ DesktopModeVisualIndicator.DragStartState
+ .getDragStartState(relevantDecor.mTaskInfo);
+ if (dragStartState == null) return;
final DesktopModeVisualIndicator.IndicatorType indicatorType =
mDesktopTasksController.updateVisualIndicator(
relevantDecor.mTaskInfo,
- relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY());
+ relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY(),
+ dragStartState);
if (indicatorType != TO_FULLSCREEN_INDICATOR) {
if (mMoveToDesktopAnimator == null) {
mMoveToDesktopAnimator = new MoveToDesktopAnimator(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
index 0f2de700d3ae..cb9781e86c87 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
@@ -82,32 +82,26 @@ public class DragPositioningCallbackUtility {
final int oldRight = repositionTaskBounds.right;
final int oldBottom = repositionTaskBounds.bottom;
-
repositionTaskBounds.set(taskBoundsAtDragStart);
// Make sure the new resizing destination in any direction falls within the stable bounds.
- // If not, set the bounds back to the old location that was valid to avoid conflicts with
- // some regions such as the gesture area.
if ((ctrlType & CTRL_TYPE_LEFT) != 0) {
- final int candidateLeft = repositionTaskBounds.left + (int) delta.x;
- repositionTaskBounds.left = (candidateLeft > stableBounds.left)
- ? candidateLeft : oldLeft;
+ repositionTaskBounds.left = Math.max(repositionTaskBounds.left + (int) delta.x,
+ stableBounds.left);
}
if ((ctrlType & CTRL_TYPE_RIGHT) != 0) {
- final int candidateRight = repositionTaskBounds.right + (int) delta.x;
- repositionTaskBounds.right = (candidateRight < stableBounds.right)
- ? candidateRight : oldRight;
+ repositionTaskBounds.right = Math.min(repositionTaskBounds.right + (int) delta.x,
+ stableBounds.right);
}
if ((ctrlType & CTRL_TYPE_TOP) != 0) {
- final int candidateTop = repositionTaskBounds.top + (int) delta.y;
- repositionTaskBounds.top = (candidateTop > stableBounds.top)
- ? candidateTop : oldTop;
+ repositionTaskBounds.top = Math.max(repositionTaskBounds.top + (int) delta.y,
+ stableBounds.top);
}
if ((ctrlType & CTRL_TYPE_BOTTOM) != 0) {
- final int candidateBottom = repositionTaskBounds.bottom + (int) delta.y;
- repositionTaskBounds.bottom = (candidateBottom < stableBounds.bottom)
- ? candidateBottom : oldBottom;
+ repositionTaskBounds.bottom = Math.min(repositionTaskBounds.bottom + (int) delta.y,
+ stableBounds.bottom);
}
+
// If width or height are negative or exceeding the width or height constraints, revert the
// respective bounds to use previous bound dimensions.
if (isExceedingWidthConstraint(repositionTaskBounds, stableBounds, displayController,
@@ -120,14 +114,12 @@ public class DragPositioningCallbackUtility {
repositionTaskBounds.top = oldTop;
repositionTaskBounds.bottom = oldBottom;
}
- // If there are no changes to the bounds after checking new bounds against minimum width
- // and height, do not set bounds and return false
- if (oldLeft == repositionTaskBounds.left && oldTop == repositionTaskBounds.top
- && oldRight == repositionTaskBounds.right
- && oldBottom == repositionTaskBounds.bottom) {
- return false;
- }
- return true;
+
+ // If there are no changes to the bounds after checking new bounds against minimum and
+ // maximum width and height, do not set bounds and return false
+ return oldLeft != repositionTaskBounds.left || oldTop != repositionTaskBounds.top
+ || oldRight != repositionTaskBounds.right
+ || oldBottom != repositionTaskBounds.bottom;
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
index fd7bed7c60de..6dedf6da3ab7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.windowdecor;
+import static android.view.InputDevice.SOURCE_MOUSE;
import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
import static com.android.wm.shell.shared.desktopmode.DesktopModeFlags.EDGE_DRAG_RESIZE;
@@ -166,7 +167,10 @@ final class DragResizeWindowGeometry {
static boolean isEdgeResizePermitted(@NonNull Context context, @NonNull MotionEvent e) {
if (EDGE_DRAG_RESIZE.isEnabled(context)) {
return e.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS
- || e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE;
+ || e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE
+ // Touchpad input
+ || (e.isFromSource(SOURCE_MOUSE)
+ && e.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER);
} else {
return e.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE;
}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindow.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindow.kt
new file mode 100644
index 000000000000..5bc975bbd565
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindow.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.scenarios
+
+import android.platform.test.annotations.Postsubmit
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.MailAppHelper
+import com.android.server.wm.flicker.helpers.NewTasksAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.BlockJUnit4ClassRunner
+
+@RunWith(BlockJUnit4ClassRunner::class)
+@Postsubmit
+open class ResizeAppCornerMultiWindow
+@JvmOverloads
+constructor(val rotation: Rotation = Rotation.ROTATION_0,
+ val horizontalChange: Int = 50,
+ val verticalChange: Int = -50) {
+
+ private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+ private val tapl = LauncherInstrumentation()
+ private val wmHelper = WindowManagerStateHelper(instrumentation)
+ private val device = UiDevice.getInstance(instrumentation)
+ private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+ private val mailApp = DesktopModeAppHelper(MailAppHelper(instrumentation))
+ private val newTasksApp = DesktopModeAppHelper(NewTasksAppHelper(instrumentation))
+ private val imeApp = DesktopModeAppHelper(ImeAppHelper(instrumentation))
+
+ @Rule
+ @JvmField
+ val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+
+ @Before
+ fun setup() {
+ Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+ tapl.setEnableRotation(true)
+ tapl.setExpectedRotation(rotation.value)
+ testApp.enterDesktopWithDrag(wmHelper, device)
+ mailApp.launchViaIntent(wmHelper)
+ newTasksApp.launchViaIntent(wmHelper)
+ imeApp.launchViaIntent(wmHelper)
+ }
+
+ @Test
+ open fun resizeAppWithCornerResize() {
+ imeApp.cornerResize(wmHelper,
+ device,
+ DesktopModeAppHelper.Corners.RIGHT_TOP,
+ horizontalChange,
+ verticalChange)
+ }
+
+ @After
+ fun teardown() {
+ testApp.exit(wmHelper)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIComponentTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIComponentTest.kt
new file mode 100644
index 000000000000..2c203c466c6e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIComponentTest.kt
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.compatui.impl
+
+import android.app.ActivityManager
+import android.graphics.Point
+import android.testing.AndroidTestingRunner
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.common.DisplayLayout
+import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.compatui.api.CompatUIComponent
+import com.android.wm.shell.compatui.api.CompatUIComponentState
+import com.android.wm.shell.compatui.api.CompatUIInfo
+import com.android.wm.shell.compatui.api.CompatUIState
+import junit.framework.Assert.assertEquals
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+
+/**
+ * Tests for {@link CompatUIComponent}.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:CompatUIComponentTest
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class CompatUIComponentTest : ShellTestCase() {
+
+ private lateinit var component: CompatUIComponent
+ private lateinit var layout: FakeCompatUILayout
+ private lateinit var spec: FakeCompatUISpec
+ private lateinit var state: CompatUIState
+ private lateinit var info: CompatUIInfo
+ private lateinit var syncQueue: SyncTransactionQueue
+ private lateinit var displayLayout: DisplayLayout
+ private lateinit var view: View
+ private lateinit var position: Point
+ private lateinit var componentState: CompatUIComponentState
+
+ @JvmField
+ @Rule
+ val compatUIHandlerRule: CompatUIHandlerRule = CompatUIHandlerRule()
+
+ @Before
+ fun setUp() {
+ state = CompatUIState()
+ view = View(mContext)
+ position = Point(123, 456)
+ layout = FakeCompatUILayout(viewBuilderReturn = view, positionBuilderReturn = position)
+ spec = FakeCompatUISpec("comp", layout = layout)
+ info = testCompatUIInfo()
+ syncQueue = mock<SyncTransactionQueue>()
+ displayLayout = mock<DisplayLayout>()
+ component =
+ CompatUIComponent(spec.getSpec(),
+ "compId",
+ mContext,
+ state,
+ info,
+ syncQueue,
+ displayLayout)
+ componentState = object : CompatUIComponentState {}
+ state.registerUIComponent("compId", component, componentState)
+ }
+
+ @Test
+ fun `when initLayout is invoked spec fields are used`() {
+ compatUIHandlerRule.postBlocking {
+ component.initLayout(info)
+ }
+ with(layout) {
+ assertViewBuilderInvocation(1)
+ assertEquals(info, lastViewBuilderCompatUIInfo)
+ assertEquals(componentState, lastViewBuilderCompState)
+ assertViewBinderInvocation(0)
+ assertPositionFactoryInvocation(1)
+ assertEquals(info, lastPositionFactoryCompatUIInfo)
+ assertEquals(view, lastPositionFactoryView)
+ assertEquals(componentState, lastPositionFactoryCompState)
+ assertEquals(state.sharedState, lastPositionFactorySharedState)
+ }
+ }
+
+ @Test
+ fun `when update is invoked only position and binder spec fields are used`() {
+ compatUIHandlerRule.postBlocking {
+ component.initLayout(info)
+ layout.resetState()
+ component.update(info)
+ }
+ with(layout) {
+ assertViewBuilderInvocation(0)
+ assertViewBinderInvocation(1)
+ assertPositionFactoryInvocation(1)
+ }
+ }
+
+ private fun testCompatUIInfo(): CompatUIInfo {
+ val taskInfo = ActivityManager.RunningTaskInfo()
+ taskInfo.taskId = 1
+ return CompatUIInfo(taskInfo, null)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIHandlerRule.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIHandlerRule.kt
new file mode 100644
index 000000000000..4b8b65c784e9
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIHandlerRule.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.compatui.impl
+
+import android.os.HandlerThread
+import java.util.concurrent.CountDownLatch
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/**
+ * Utility {@link TestRule} to manage Handlers in Compat UI tests.
+ */
+class CompatUIHandlerRule : TestRule {
+
+ private lateinit var handler: HandlerThread
+
+ /**
+ * Makes the HandlerThread available during the test
+ */
+ override fun apply(base: Statement?, description: Description?): Statement {
+ handler = HandlerThread("CompatUIHandler").apply {
+ start()
+ }
+ return object : Statement() {
+ @Throws(Throwable::class)
+ override fun evaluate() {
+ try {
+ base!!.evaluate()
+ } finally {
+ handler.quitSafely()
+ }
+ }
+ }
+ }
+
+ /**
+ * Posts a {@link Runnable} for the Handler
+ * @param runnable The Runnable to execute
+ */
+ fun postBlocking(runnable: Runnable) {
+ val countDown = CountDownLatch(/* count = */ 1)
+ handler.threadHandler.post{
+ runnable.run()
+ countDown.countDown()
+ }
+ try {
+ countDown.await()
+ } catch (e: InterruptedException) {
+ // No-op
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIStateUtil.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIStateUtil.kt
index 43bd41275daa..4f0e5b9cbfbf 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIStateUtil.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/CompatUIStateUtil.kt
@@ -17,7 +17,6 @@
package com.android.wm.shell.compatui.impl
import com.android.wm.shell.compatui.api.CompatUIComponentState
-import com.android.wm.shell.compatui.api.CompatUISpec
import com.android.wm.shell.compatui.api.CompatUIState
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertNotNull
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandlerTest.kt
index 8136074b7aa6..66852ad5ab5d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandlerTest.kt
@@ -18,13 +18,21 @@ package com.android.wm.shell.compatui.impl
import android.app.ActivityManager
import android.testing.AndroidTestingRunner
+import android.view.View
import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestShellExecutor
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.compatui.api.CompatUIComponentState
import com.android.wm.shell.compatui.api.CompatUIInfo
import com.android.wm.shell.compatui.api.CompatUIState
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
/**
* Tests for {@link DefaultCompatUIHandler}.
@@ -34,20 +42,37 @@ import org.junit.runner.RunWith
*/
@RunWith(AndroidTestingRunner::class)
@SmallTest
-class DefaultCompatUIHandlerTest {
+class DefaultCompatUIHandlerTest : ShellTestCase() {
+
+ @JvmField
+ @Rule
+ val compatUIHandlerRule: CompatUIHandlerRule = CompatUIHandlerRule()
lateinit var compatUIRepository: FakeCompatUIRepository
lateinit var compatUIHandler: DefaultCompatUIHandler
lateinit var compatUIState: CompatUIState
lateinit var fakeIdGenerator: FakeCompatUIComponentIdGenerator
+ lateinit var syncQueue: SyncTransactionQueue
+ lateinit var displayController: DisplayController
+ lateinit var shellExecutor: TestShellExecutor
+ lateinit var componentFactory: FakeCompatUIComponentFactory
@Before
fun setUp() {
+ shellExecutor = TestShellExecutor()
compatUIRepository = FakeCompatUIRepository()
compatUIState = CompatUIState()
fakeIdGenerator = FakeCompatUIComponentIdGenerator("compId")
- compatUIHandler = DefaultCompatUIHandler(compatUIRepository, compatUIState,
- fakeIdGenerator)
+ syncQueue = mock<SyncTransactionQueue>()
+ displayController = mock<DisplayController>()
+ componentFactory = FakeCompatUIComponentFactory(mContext, syncQueue, displayController)
+ compatUIHandler =
+ DefaultCompatUIHandler(
+ compatUIRepository,
+ compatUIState,
+ fakeIdGenerator,
+ componentFactory,
+ shellExecutor)
}
@Test
@@ -57,12 +82,18 @@ class DefaultCompatUIHandlerTest {
creationReturn = false,
removalReturn = false
)
- val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle).getSpec()
+ val fakeCompatUILayout = FakeCompatUILayout(viewBuilderReturn = View(mContext))
+ val fakeCompatUISpec =
+ FakeCompatUISpec(name = "one",
+ lifecycle = fakeLifecycle,
+ layout = fakeCompatUILayout).getSpec()
compatUIRepository.addSpec(fakeCompatUISpec)
val generatedId = fakeIdGenerator.generatedComponentId
- compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
fakeIdGenerator.assertGenerateInvocations(1)
fakeLifecycle.assertCreationInvocation(1)
@@ -71,7 +102,9 @@ class DefaultCompatUIHandlerTest {
compatUIState.assertHasNoStateFor(generatedId)
compatUIState.assertHasNoComponentFor(generatedId)
- compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
fakeLifecycle.assertCreationInvocation(2)
fakeLifecycle.assertRemovalInvocation(0)
fakeLifecycle.assertInitialStateInvocation(0)
@@ -86,12 +119,18 @@ class DefaultCompatUIHandlerTest {
creationReturn = true,
removalReturn = false
)
- val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle).getSpec()
+ val fakeCompatUILayout = FakeCompatUILayout(viewBuilderReturn = View(mContext))
+ val fakeCompatUISpec =
+ FakeCompatUISpec(name = "one",
+ lifecycle = fakeLifecycle,
+ layout = fakeCompatUILayout).getSpec()
compatUIRepository.addSpec(fakeCompatUISpec)
val generatedId = fakeIdGenerator.generatedComponentId
- compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
fakeLifecycle.assertCreationInvocation(1)
fakeLifecycle.assertRemovalInvocation(0)
@@ -99,7 +138,9 @@ class DefaultCompatUIHandlerTest {
compatUIState.assertHasNoStateFor(generatedId)
compatUIState.assertHasComponentFor(generatedId)
- compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
fakeLifecycle.assertCreationInvocation(1)
fakeLifecycle.assertRemovalInvocation(1)
@@ -117,12 +158,18 @@ class DefaultCompatUIHandlerTest {
removalReturn = false,
initialState = { _, _ -> fakeComponentState }
)
- val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle).getSpec()
+ val fakeCompatUILayout = FakeCompatUILayout(viewBuilderReturn = View(mContext))
+ val fakeCompatUISpec =
+ FakeCompatUISpec(name = "one",
+ lifecycle = fakeLifecycle,
+ layout = fakeCompatUILayout).getSpec()
compatUIRepository.addSpec(fakeCompatUISpec)
val generatedId = fakeIdGenerator.generatedComponentId
- compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
fakeLifecycle.assertCreationInvocation(1)
fakeLifecycle.assertRemovalInvocation(0)
@@ -130,7 +177,9 @@ class DefaultCompatUIHandlerTest {
compatUIState.assertHasStateEqualsTo(generatedId, fakeComponentState)
compatUIState.assertHasComponentFor(generatedId)
- compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
fakeLifecycle.assertCreationInvocation(1)
fakeLifecycle.assertRemovalInvocation(1)
@@ -148,12 +197,18 @@ class DefaultCompatUIHandlerTest {
removalReturn = true,
initialState = { _, _ -> fakeComponentState }
)
- val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle).getSpec()
+ val fakeCompatUILayout = FakeCompatUILayout(viewBuilderReturn = View(mContext))
+ val fakeCompatUISpec =
+ FakeCompatUISpec(name = "one",
+ lifecycle = fakeLifecycle,
+ layout = fakeCompatUILayout).getSpec()
compatUIRepository.addSpec(fakeCompatUISpec)
val generatedId = fakeIdGenerator.generatedComponentId
- compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
fakeLifecycle.assertCreationInvocation(1)
fakeLifecycle.assertRemovalInvocation(0)
@@ -161,7 +216,9 @@ class DefaultCompatUIHandlerTest {
compatUIState.assertHasStateEqualsTo(generatedId, fakeComponentState)
compatUIState.assertHasComponentFor(generatedId)
- compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
fakeLifecycle.assertCreationInvocation(1)
fakeLifecycle.assertRemovalInvocation(1)
@@ -177,17 +234,56 @@ class DefaultCompatUIHandlerTest {
creationReturn = true,
removalReturn = true,
)
- val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle).getSpec()
+ val fakeCompatUILayout = FakeCompatUILayout(viewBuilderReturn = View(mContext))
+ val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle,
+ fakeCompatUILayout).getSpec()
compatUIRepository.addSpec(fakeCompatUISpec)
// Component creation
fakeIdGenerator.assertGenerateInvocations(0)
- compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
fakeIdGenerator.assertGenerateInvocations(1)
- compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
fakeIdGenerator.assertGenerateInvocations(2)
}
+ @Test
+ fun `viewBuilder and viewBinder invoked if component is created and released when destroyed`() {
+ // We add a spec to the repository
+ val fakeLifecycle = FakeCompatUILifecyclePredicates(
+ creationReturn = true,
+ removalReturn = true,
+ )
+ val fakeCompatUILayout = FakeCompatUILayout(viewBuilderReturn = View(mContext))
+ val fakeCompatUISpec = FakeCompatUISpec("one", fakeLifecycle,
+ fakeCompatUILayout).getSpec()
+ compatUIRepository.addSpec(fakeCompatUISpec)
+
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
+ shellExecutor.flushAll()
+ componentFactory.assertInvocations(1)
+ fakeCompatUILayout.assertViewBuilderInvocation(1)
+ fakeCompatUILayout.assertViewBinderInvocation(1)
+ fakeCompatUILayout.assertViewReleaserInvocation(0)
+
+ compatUIHandlerRule.postBlocking {
+ compatUIHandler.onCompatInfoChanged(testCompatUIInfo())
+ }
+ shellExecutor.flushAll()
+
+ componentFactory.assertInvocations(1)
+ fakeCompatUILayout.assertViewBuilderInvocation(1)
+ fakeCompatUILayout.assertViewBinderInvocation(1)
+ fakeCompatUILayout.assertViewReleaserInvocation(1)
+ }
+
+
private fun testCompatUIInfo(): CompatUIInfo {
val taskInfo = ActivityManager.RunningTaskInfo()
taskInfo.taskId = 1
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt
index e35acb2ca0e9..319122d1e051 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/DefaultCompatUIRepositoryTest.kt
@@ -16,9 +16,13 @@
package com.android.wm.shell.compatui.impl
+
+import android.graphics.Point
import android.platform.test.flag.junit.DeviceFlagsValueProvider
import android.testing.AndroidTestingRunner
+import android.view.View
import androidx.test.filters.SmallTest
+import com.android.wm.shell.compatui.api.CompatUILayout
import com.android.wm.shell.compatui.api.CompatUILifecyclePredicates
import com.android.wm.shell.compatui.api.CompatUIRepository
import com.android.wm.shell.compatui.api.CompatUISpec
@@ -89,8 +93,14 @@ class DefaultCompatUIRepositoryTest {
}
private fun specById(name: String): CompatUISpec =
- CompatUISpec(name = name, lifecycle = CompatUILifecyclePredicates(
- creationPredicate = { _, _ -> true },
- removalPredicate = { _, _, _ -> true }
- ))
+ CompatUISpec(name = name,
+ lifecycle = CompatUILifecyclePredicates(
+ creationPredicate = { _, _ -> true },
+ removalPredicate = { _, _, _ -> true }
+ ),
+ layout = CompatUILayout(
+ viewBuilder = { ctx, _, _ -> View(ctx) },
+ positionFactory = { _, _, _, _ -> Point(0, 0) }
+ )
+ )
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIComponentFactory.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIComponentFactory.kt
new file mode 100644
index 000000000000..782add84a36c
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUIComponentFactory.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.compatui.impl
+
+import android.content.Context
+import com.android.wm.shell.common.DisplayController
+import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.compatui.api.CompatUIComponent
+import com.android.wm.shell.compatui.api.CompatUIComponentFactory
+import com.android.wm.shell.compatui.api.CompatUIInfo
+import com.android.wm.shell.compatui.api.CompatUISpec
+import com.android.wm.shell.compatui.api.CompatUIState
+import junit.framework.Assert.assertEquals
+
+/**
+ * Fake {@link CompatUIComponentFactory} implementation.
+ */
+class FakeCompatUIComponentFactory(
+ private val context: Context,
+ private val syncQueue: SyncTransactionQueue,
+ private val displayController: DisplayController
+) : CompatUIComponentFactory {
+
+ var lastSpec: CompatUISpec? = null
+ var lastCompId: String? = null
+ var lastState: CompatUIState? = null
+ var lastInfo: CompatUIInfo? = null
+
+ var numberInvocations = 0
+
+ override fun create(
+ spec: CompatUISpec,
+ compId: String,
+ state: CompatUIState,
+ compatUIInfo: CompatUIInfo
+ ): CompatUIComponent {
+ lastSpec = spec
+ lastCompId = compId
+ lastState = state
+ lastInfo = compatUIInfo
+ numberInvocations++
+ return CompatUIComponent(
+ spec,
+ compId,
+ context,
+ state,
+ compatUIInfo,
+ syncQueue,
+ displayController.getDisplayLayout(compatUIInfo.taskInfo.displayId)
+ )
+ }
+
+ fun assertInvocations(expected: Int) =
+ assertEquals(expected, numberInvocations)
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILayout.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILayout.kt
new file mode 100644
index 000000000000..d7a178ab69e8
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILayout.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.compatui.impl
+
+import android.content.Context
+import android.graphics.Point
+import android.view.View
+import com.android.wm.shell.compatui.api.CompatUIComponentState
+import com.android.wm.shell.compatui.api.CompatUIInfo
+import com.android.wm.shell.compatui.api.CompatUILayout
+import com.android.wm.shell.compatui.api.CompatUISharedState
+import junit.framework.Assert.assertEquals
+
+/**
+ * Fake class for {@link CompatUILayout}
+ */
+class FakeCompatUILayout(
+ private val zOrderReturn: Int = 0,
+ private val layoutParamFlagsReturn: Int = 0,
+ private val viewBuilderReturn: View,
+ private val positionBuilderReturn: Point = Point(0, 0)
+) {
+
+ var viewBuilderInvocation = 0
+ var viewBinderInvocation = 0
+ var positionFactoryInvocation = 0
+ var viewReleaserInvocation = 0
+
+ var lastViewBuilderContext: Context? = null
+ var lastViewBuilderCompatUIInfo: CompatUIInfo? = null
+ var lastViewBuilderCompState: CompatUIComponentState? = null
+ var lastViewBinderView: View? = null
+ var lastViewBinderCompatUIInfo: CompatUIInfo? = null
+ var lastViewBinderSharedState: CompatUISharedState? = null
+ var lastViewBinderCompState: CompatUIComponentState? = null
+ var lastPositionFactoryView: View? = null
+ var lastPositionFactoryCompatUIInfo: CompatUIInfo? = null
+ var lastPositionFactorySharedState: CompatUISharedState? = null
+ var lastPositionFactoryCompState: CompatUIComponentState? = null
+
+ fun getLayout() = CompatUILayout(
+ zOrder = zOrderReturn,
+ layoutParamFlags = layoutParamFlagsReturn,
+ viewBuilder = { ctx, info, componentState ->
+ lastViewBuilderContext = ctx
+ lastViewBuilderCompatUIInfo = info
+ lastViewBuilderCompState = componentState
+ viewBuilderInvocation++
+ viewBuilderReturn
+ },
+ viewBinder = { view, info, sharedState, componentState ->
+ lastViewBinderView = view
+ lastViewBinderCompatUIInfo = info
+ lastViewBinderCompState = componentState
+ lastViewBinderSharedState = sharedState
+ viewBinderInvocation++
+ },
+ positionFactory = { view, info, sharedState, componentState ->
+ lastPositionFactoryView = view
+ lastPositionFactoryCompatUIInfo = info
+ lastPositionFactoryCompState = componentState
+ lastPositionFactorySharedState = sharedState
+ positionFactoryInvocation++
+ positionBuilderReturn
+ },
+ viewReleaser = { viewReleaserInvocation++ }
+ )
+
+ fun assertViewBuilderInvocation(expected: Int) =
+ assertEquals(expected, viewBuilderInvocation)
+
+ fun assertViewBinderInvocation(expected: Int) =
+ assertEquals(expected, viewBinderInvocation)
+
+ fun assertViewReleaserInvocation(expected: Int) =
+ assertEquals(expected, viewReleaserInvocation)
+
+ fun assertPositionFactoryInvocation(expected: Int) =
+ assertEquals(expected, positionFactoryInvocation)
+
+ fun resetState() {
+ viewBuilderInvocation = 0
+ viewBinderInvocation = 0
+ positionFactoryInvocation = 0
+ viewReleaserInvocation = 0
+ lastViewBuilderCompatUIInfo = null
+ lastViewBuilderCompState = null
+ lastViewBinderView = null
+ lastViewBinderCompatUIInfo = null
+ lastViewBinderSharedState = null
+ lastViewBinderCompState = null
+ lastPositionFactoryView = null
+ lastPositionFactoryCompatUIInfo = null
+ lastPositionFactorySharedState = null
+ lastPositionFactoryCompState = null
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILifecyclePredicates.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILifecyclePredicates.kt
index bbaa2db07aaa..f742ca32e63d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILifecyclePredicates.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUILifecyclePredicates.kt
@@ -26,8 +26,8 @@ import junit.framework.Assert.assertEquals
* Fake class for {@link CompatUILifecycle}
*/
class FakeCompatUILifecyclePredicates(
- private val creationReturn: Boolean,
- private val removalReturn: Boolean,
+ private val creationReturn: Boolean = false,
+ private val removalReturn: Boolean = false,
private val initialState: (
CompatUIInfo,
CompatUISharedState
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUISpec.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUISpec.kt
index 1ecd52e2b3ff..0912bf115666 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUISpec.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/impl/FakeCompatUISpec.kt
@@ -23,10 +23,13 @@ import com.android.wm.shell.compatui.api.CompatUISpec
*/
class FakeCompatUISpec(
val name: String,
- val lifecycle: FakeCompatUILifecyclePredicates
+ val lifecycle: FakeCompatUILifecyclePredicates = FakeCompatUILifecyclePredicates(),
+ val layout: FakeCompatUILayout
) {
fun getSpec(): CompatUISpec = CompatUISpec(
name = name,
- lifecycle = lifecycle.getLifecycle()
+ log = {str -> android.util.Log.d("COMPAT_UI_TEST", str)},
+ lifecycle = lifecycle.getLifecycle(),
+ layout = layout.getLayout()
)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
index 2dea43b508ae..f558e87c4ed7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
@@ -17,9 +17,6 @@
package com.android.wm.shell.desktopmode
import android.app.ActivityManager.RunningTaskInfo
-import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
-import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
-import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
import android.graphics.Rect
import android.graphics.Region
import android.testing.AndroidTestingRunner
@@ -38,6 +35,11 @@ import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.kotlin.whenever
+/**
+ * Test class for [DesktopModeVisualIndicator]
+ *
+ * Usage: atest WMShellUnitTests:DesktopModeVisualIndicatorTest
+ */
@SmallTest
@RunWith(AndroidTestingRunner::class)
class DesktopModeVisualIndicatorTest : ShellTestCase() {
@@ -52,8 +54,6 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
@Before
fun setUp() {
- visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo, displayController,
- context, taskSurface, taskDisplayAreaOrganizer)
whenever(displayLayout.width()).thenReturn(DISPLAY_BOUNDS.width())
whenever(displayLayout.height()).thenReturn(DISPLAY_BOUNDS.height())
whenever(displayLayout.stableInsets()).thenReturn(STABLE_INSETS)
@@ -61,41 +61,52 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
@Test
fun testFullscreenRegionCalculation() {
- var testRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
- WINDOWING_MODE_FULLSCREEN, CAPTION_HEIGHT)
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
+ var testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 2400, 2 * STABLE_INSETS.top))
- testRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
- WINDOWING_MODE_FREEFORM, CAPTION_HEIGHT)
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM)
+ testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT)
val transitionHeight = context.resources.getDimensionPixelSize(
R.dimen.desktop_mode_transition_region_thickness)
val toFullscreenScale = mContext.resources.getFloat(
R.dimen.desktop_mode_fullscreen_region_scale
)
val toFullscreenWidth = displayLayout.width() * toFullscreenScale
-
assertThat(testRegion.bounds).isEqualTo(Rect(
(DISPLAY_BOUNDS.width() / 2f - toFullscreenWidth / 2f).toInt(),
-50,
(DISPLAY_BOUNDS.width() / 2f + toFullscreenWidth / 2f).toInt(),
transitionHeight))
- testRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
- WINDOWING_MODE_MULTI_WINDOW, CAPTION_HEIGHT)
+
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
+ testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 2400, 2 * STABLE_INSETS.top))
+
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT)
+ testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT)
+ assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 2400, transitionHeight))
}
@Test
fun testSplitLeftRegionCalculation() {
val transitionHeight = context.resources.getDimensionPixelSize(
R.dimen.desktop_mode_split_from_desktop_height)
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
var testRegion = visualIndicator.calculateSplitLeftRegion(displayLayout,
- WINDOWING_MODE_FULLSCREEN, TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
+ TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 32, 1600))
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM)
testRegion = visualIndicator.calculateSplitLeftRegion(displayLayout,
- WINDOWING_MODE_FREEFORM, TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
+ TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(0, transitionHeight, 32, 1600))
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
testRegion = visualIndicator.calculateSplitLeftRegion(displayLayout,
- WINDOWING_MODE_MULTI_WINDOW, TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
+ TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
+ assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 32, 1600))
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT)
+ testRegion = visualIndicator.calculateSplitLeftRegion(displayLayout,
+ TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 32, 1600))
}
@@ -103,27 +114,35 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
fun testSplitRightRegionCalculation() {
val transitionHeight = context.resources.getDimensionPixelSize(
R.dimen.desktop_mode_split_from_desktop_height)
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
var testRegion = visualIndicator.calculateSplitRightRegion(displayLayout,
- WINDOWING_MODE_FULLSCREEN, TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
+ TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(2368, -50, 2400, 1600))
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM)
testRegion = visualIndicator.calculateSplitRightRegion(displayLayout,
- WINDOWING_MODE_FREEFORM, TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
+ TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(2368, transitionHeight, 2400, 1600))
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
+ testRegion = visualIndicator.calculateSplitRightRegion(displayLayout,
+ TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
+ assertThat(testRegion.bounds).isEqualTo(Rect(2368, -50, 2400, 1600))
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT)
testRegion = visualIndicator.calculateSplitRightRegion(displayLayout,
- WINDOWING_MODE_MULTI_WINDOW, TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
+ TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
assertThat(testRegion.bounds).isEqualTo(Rect(2368, -50, 2400, 1600))
}
@Test
fun testToDesktopRegionCalculation() {
+ createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
val fullscreenRegion = visualIndicator.calculateFullscreenRegion(displayLayout,
- WINDOWING_MODE_FULLSCREEN, CAPTION_HEIGHT)
+ CAPTION_HEIGHT)
val splitLeftRegion = visualIndicator.calculateSplitLeftRegion(displayLayout,
- WINDOWING_MODE_FULLSCREEN, TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
+ TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
val splitRightRegion = visualIndicator.calculateSplitRightRegion(displayLayout,
- WINDOWING_MODE_FULLSCREEN, TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
+ TRANSITION_AREA_WIDTH, CAPTION_HEIGHT)
val desktopRegion = visualIndicator.calculateToDesktopRegion(displayLayout,
- WINDOWING_MODE_FULLSCREEN, splitLeftRegion, splitRightRegion, fullscreenRegion)
+ splitLeftRegion, splitRightRegion, fullscreenRegion)
var testRegion = Region()
testRegion.union(DISPLAY_BOUNDS)
testRegion.op(splitLeftRegion, Region.Op.DIFFERENCE)
@@ -132,6 +151,11 @@ class DesktopModeVisualIndicatorTest : ShellTestCase() {
assertThat(desktopRegion).isEqualTo(testRegion)
}
+ private fun createVisualIndicator(dragStartState: DesktopModeVisualIndicator.DragStartState) {
+ visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo, displayController,
+ context, taskSurface, taskDisplayAreaOrganizer, dragStartState)
+ }
+
companion object {
private const val TRANSITION_AREA_WIDTH = 32
private const val CAPTION_HEIGHT = 50
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 616f3104eb88..a841e168af18 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -160,6 +160,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Mock lateinit var mReturnToDragStartAnimator: ReturnToDragStartAnimator
@Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler
@Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler
+ @Mock lateinit var dragAndDropTransitionHandler: DesktopModeDragAndDropTransitionHandler
@Mock
lateinit var toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler
@Mock lateinit var dragToDesktopTransitionHandler: DragToDesktopTransitionHandler
@@ -254,6 +255,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
mReturnToDragStartAnimator,
enterDesktopTransitionHandler,
exitDesktopTransitionHandler,
+ dragAndDropTransitionHandler,
toggleResizeDesktopTaskTransitionHandler,
dragToDesktopTransitionHandler,
taskRepository,
@@ -2262,27 +2264,6 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
@Test
- fun desktopTasksVisibilityChange_visible_setLaunchAdjacentDisabled() {
- val task = setUpFreeformTask()
- clearInvocations(launchAdjacentController)
-
- markTaskVisible(task)
- shellExecutor.flushAll()
- verify(launchAdjacentController).launchAdjacentEnabled = false
- }
-
- @Test
- fun desktopTasksVisibilityChange_invisible_setLaunchAdjacentEnabled() {
- val task = setUpFreeformTask()
- markTaskVisible(task)
- clearInvocations(launchAdjacentController)
-
- markTaskHidden(task)
- shellExecutor.flushAll()
- verify(launchAdjacentController).launchAdjacentEnabled = true
- }
-
- @Test
fun moveFocusedTaskToDesktop_fullscreenTaskIsMovedToDesktop() {
val task1 = setUpFullscreenTask()
val task2 = setUpFullscreenTask()
@@ -2387,7 +2368,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun dragToDesktop_landscapeDevice_resizable_undefinedOrientation_defaultLandscapeBounds() {
val spyController = spy(controller)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR)
val task = setUpFullscreenTask()
@@ -2403,7 +2384,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun dragToDesktop_landscapeDevice_resizable_landscapeOrientation_defaultLandscapeBounds() {
val spyController = spy(controller)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR)
val task = setUpFullscreenTask(screenOrientation = SCREEN_ORIENTATION_LANDSCAPE)
@@ -2419,7 +2400,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun dragToDesktop_landscapeDevice_resizable_portraitOrientation_resizablePortraitBounds() {
val spyController = spy(controller)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR)
val task =
@@ -2436,7 +2417,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun dragToDesktop_landscapeDevice_unResizable_landscapeOrientation_defaultLandscapeBounds() {
val spyController = spy(controller)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR)
val task =
@@ -2453,7 +2434,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun dragToDesktop_landscapeDevice_unResizable_portraitOrientation_unResizablePortraitBounds() {
val spyController = spy(controller)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR)
val task =
@@ -2473,7 +2454,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun dragToDesktop_portraitDevice_resizable_undefinedOrientation_defaultPortraitBounds() {
val spyController = spy(controller)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR)
val task = setUpFullscreenTask(deviceOrientation = ORIENTATION_PORTRAIT)
@@ -2489,7 +2470,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun dragToDesktop_portraitDevice_resizable_portraitOrientation_defaultPortraitBounds() {
val spyController = spy(controller)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR)
val task =
@@ -2508,7 +2489,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun dragToDesktop_portraitDevice_resizable_landscapeOrientation_resizableLandscapeBounds() {
val spyController = spy(controller)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR)
val task =
@@ -2528,7 +2509,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun dragToDesktop_portraitDevice_unResizable_portraitOrientation_defaultPortraitBounds() {
val spyController = spy(controller)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR)
val task =
@@ -2548,7 +2529,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
fun dragToDesktop_portraitDevice_unResizable_landscapeOrientation_unResizableLandscapeBounds() {
val spyController = spy(controller)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR)
val task =
@@ -2605,7 +2586,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val currentDragBounds = Rect(100, 200, 500, 1000)
whenever(spyController.getVisualIndicator()).thenReturn(desktopModeVisualIndicator)
- whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull(), anyOrNull()))
+ whenever(desktopModeVisualIndicator.updateIndicatorType(anyOrNull()))
.thenReturn(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
spyController.onDragPositioningEnd(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
index 6ec6bed860bd..763d0153071e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.app.ActivityManager;
+import android.view.SurfaceControl;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -35,6 +36,7 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSession;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestRunningTaskInfoBuilder;
+import com.android.wm.shell.common.LaunchAdjacentController;
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.sysui.ShellInit;
@@ -65,7 +67,11 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
@Mock
private WindowDecorViewModel mWindowDecorViewModel;
@Mock
+ private SurfaceControl mMockSurfaceControl;
+ @Mock
private DesktopModeTaskRepository mDesktopModeTaskRepository;
+ @Mock
+ private LaunchAdjacentController mLaunchAdjacentController;
private FreeformTaskListener mFreeformTaskListener;
private StaticMockitoSession mMockitoSession;
@@ -80,6 +86,7 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
mShellInit,
mTaskOrganizer,
Optional.of(mDesktopModeTaskRepository),
+ mLaunchAdjacentController,
mWindowDecorViewModel);
}
@@ -107,6 +114,31 @@ public final class FreeformTaskListenerTests extends ShellTestCase {
.addOrMoveFreeformTaskToTop(fullscreenTask.displayId, fullscreenTask.taskId);
}
+ @Test
+ public void testVisibilityTaskChanged_visible_setLaunchAdjacentDisabled() {
+ ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder()
+ .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
+ task.isVisible = true;
+
+ mFreeformTaskListener.onTaskAppeared(task, mMockSurfaceControl);
+
+ verify(mLaunchAdjacentController).setLaunchAdjacentEnabled(false);
+ }
+
+ @Test
+ public void testVisibilityTaskChanged_NotVisible_setLaunchAdjacentEnabled() {
+ ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder()
+ .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
+ task.isVisible = true;
+
+ mFreeformTaskListener.onTaskAppeared(task, mMockSurfaceControl);
+
+ task.isVisible = false;
+ mFreeformTaskListener.onTaskInfoChanged(task);
+
+ verify(mLaunchAdjacentController).setLaunchAdjacentEnabled(true);
+ }
+
@After
public void tearDown() {
mMockitoSession.finishMocking();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index b3d56b1a574d..0054cb6ccc8c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -25,7 +25,6 @@ import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSIT
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
-import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME;
import static com.android.wm.shell.transition.Transitions.TRANSIT_SPLIT_DISMISS;
import static com.google.common.truth.Truth.assertThat;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
index e52971120478..1f33ae69b724 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
@@ -93,7 +93,7 @@ class DragPositioningCallbackUtilityTest {
fun setup() {
MockitoAnnotations.initMocks(this)
mockitoSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT)
- .spyStatic(DesktopModeStatus::class.java).startMocking()
+ .spyStatic(DesktopModeStatus::class.java).startMocking()
whenever(taskToken.asBinder()).thenReturn(taskBinder)
whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
@@ -108,9 +108,9 @@ class DragPositioningCallbackUtilityTest {
whenever(mockContext.getResources()).thenReturn(mockResources)
whenever(mockWindowDecoration.mDecorWindowContext.resources).thenReturn(mockResources)
whenever(mockResources.getDimensionPixelSize(R.dimen.desktop_mode_minimum_window_width))
- .thenReturn(DESKTOP_MODE_MIN_WIDTH)
+ .thenReturn(DESKTOP_MODE_MIN_WIDTH)
whenever(mockResources.getDimensionPixelSize(R.dimen.desktop_mode_minimum_window_height))
- .thenReturn(DESKTOP_MODE_MIN_HEIGHT)
+ .thenReturn(DESKTOP_MODE_MIN_HEIGHT)
whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID }
}
@@ -129,9 +129,11 @@ class DragPositioningCallbackUtilityTest {
val newY = STARTING_BOUNDS.top.toFloat() + 95
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration)
+ mockWindowDecoration
+ )
assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
@@ -149,9 +151,11 @@ class DragPositioningCallbackUtilityTest {
val newY = STARTING_BOUNDS.top.toFloat() + 5
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration)
+ mockWindowDecoration
+ )
assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top + 5)
@@ -169,9 +173,11 @@ class DragPositioningCallbackUtilityTest {
val newY = STARTING_BOUNDS.top.toFloat() + 105
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration)
+ mockWindowDecoration
+ )
assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
@@ -189,9 +195,11 @@ class DragPositioningCallbackUtilityTest {
val newY = STARTING_BOUNDS.top.toFloat() + 80
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration)
+ mockWindowDecoration
+ )
assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top + 80)
assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 80)
@@ -208,9 +216,11 @@ class DragPositioningCallbackUtilityTest {
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_TOP,
repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration)
+ mockWindowDecoration
+ )
assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right)
@@ -221,52 +231,95 @@ class DragPositioningCallbackUtilityTest {
fun testDragEndSnapsTaskBoundsWhenOutsideValidDragArea() {
val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
val repositionTaskBounds = Rect(STARTING_BOUNDS)
- val validDragArea = Rect(DISPLAY_BOUNDS.left - 100,
+ val validDragArea = Rect(
+ DISPLAY_BOUNDS.left - 100,
STABLE_BOUNDS.top,
DISPLAY_BOUNDS.right - 100,
- DISPLAY_BOUNDS.bottom - 100)
+ DISPLAY_BOUNDS.bottom - 100
+ )
- DragPositioningCallbackUtility.updateTaskBounds(repositionTaskBounds, STARTING_BOUNDS,
- startingPoint, startingPoint.x - 1000, (DISPLAY_BOUNDS.bottom + 1000).toFloat())
- DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(repositionTaskBounds,
- validDragArea)
+ DragPositioningCallbackUtility.updateTaskBounds(
+ repositionTaskBounds, STARTING_BOUNDS,
+ startingPoint, startingPoint.x - 1000, (DISPLAY_BOUNDS.bottom + 1000).toFloat()
+ )
+ DragPositioningCallbackUtility.snapTaskBoundsIfNecessary(
+ repositionTaskBounds,
+ validDragArea
+ )
assertThat(repositionTaskBounds.left).isEqualTo(validDragArea.left)
assertThat(repositionTaskBounds.top).isEqualTo(validDragArea.bottom)
assertThat(repositionTaskBounds.right)
- .isEqualTo(validDragArea.left + STARTING_BOUNDS.width())
+ .isEqualTo(validDragArea.left + STARTING_BOUNDS.width())
assertThat(repositionTaskBounds.bottom)
- .isEqualTo(validDragArea.bottom + STARTING_BOUNDS.height())
+ .isEqualTo(validDragArea.bottom + STARTING_BOUNDS.height())
}
@Test
fun testChangeBounds_toDisallowedBounds_freezesAtLimit() {
- val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(),
- STARTING_BOUNDS.bottom.toFloat())
+ val startingPoint = PointF(
+ STARTING_BOUNDS.right.toFloat(),
+ STARTING_BOUNDS.bottom.toFloat()
+ )
val repositionTaskBounds = Rect(STARTING_BOUNDS)
// Initial resize to width and height 110px.
var newX = STARTING_BOUNDS.right.toFloat() + 10
var newY = STARTING_BOUNDS.bottom.toFloat() + 10
var delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- assertTrue(DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
- repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration))
+ assertTrue(
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+ repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
+ mockWindowDecoration
+ )
+ )
// Resize width to 120px, height to disallowed area which should not result in a change.
newX += 10
newY = DISALLOWED_RESIZE_AREA.top.toFloat()
delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- assertTrue(DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
- repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration))
+ assertTrue(
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+ repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
+ mockWindowDecoration
+ )
+ )
assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right + 20)
- assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom + 10)
+ assertThat(repositionTaskBounds.bottom).isEqualTo(STABLE_BOUNDS.bottom)
+ }
+
+
+ @Test
+ fun testChangeBounds_beyondStableBounds_freezesAtStableBounds() {
+ val startingPoint = PointF(
+ STARTING_BOUNDS.right.toFloat(),
+ STARTING_BOUNDS.bottom.toFloat()
+ )
+ val repositionTaskBounds = Rect(STARTING_BOUNDS)
+
+ // Resize to beyond stable bounds.
+ val newX = STARTING_BOUNDS.right.toFloat() + STABLE_BOUNDS.width()
+ val newY = STARTING_BOUNDS.bottom.toFloat() + STABLE_BOUNDS.height()
+
+ val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+ assertTrue(
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+ repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
+ mockWindowDecoration
+ )
+ )
+ assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
+ assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
+ assertThat(repositionTaskBounds.right).isEqualTo(STABLE_BOUNDS.right)
+ assertThat(repositionTaskBounds.bottom).isEqualTo(STABLE_BOUNDS.bottom)
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeLessThanMin_shouldNotChangeBounds() {
- doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) }
+ doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(mockContext) }
initializeTaskInfo(taskMinWidth = -1, taskMinHeight = -1)
val startingPoint =
PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat())
@@ -277,9 +330,11 @@ class DragPositioningCallbackUtilityTest {
val newY = STARTING_BOUNDS.bottom.toFloat() - 99
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration)
+ mockWindowDecoration
+ )
assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right)
@@ -289,7 +344,7 @@ class DragPositioningCallbackUtilityTest {
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeAllowedSize_shouldChangeBounds() {
- doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) }
+ doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(mockContext) }
initializeTaskInfo(taskMinWidth = -1, taskMinHeight = -1)
val startingPoint =
PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat())
@@ -300,9 +355,11 @@ class DragPositioningCallbackUtilityTest {
val newY = STARTING_BOUNDS.bottom.toFloat() - 80
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration)
+ mockWindowDecoration
+ )
assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 80)
@@ -321,9 +378,11 @@ class DragPositioningCallbackUtilityTest {
val newY = STARTING_BOUNDS.bottom.toFloat() - 99
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration)
+ mockWindowDecoration
+ )
assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right)
@@ -342,9 +401,11 @@ class DragPositioningCallbackUtilityTest {
val newY = STARTING_BOUNDS.bottom.toFloat() - 50
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
repositionTaskBounds, STARTING_BOUNDS, STABLE_BOUNDS, delta, mockDisplayController,
- mockWindowDecoration)
+ mockWindowDecoration
+ )
assertThat(repositionTaskBounds.left).isEqualTo(STARTING_BOUNDS.left)
assertThat(repositionTaskBounds.top).isEqualTo(STARTING_BOUNDS.top)
assertThat(repositionTaskBounds.right).isEqualTo(STARTING_BOUNDS.right - 50)
@@ -355,8 +416,10 @@ class DragPositioningCallbackUtilityTest {
@DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
fun testChangeBounds_windowSizeExceedsStableBounds_shouldBeAllowedToChangeBounds() {
val startingPoint =
- PointF(OFF_CENTER_STARTING_BOUNDS.right.toFloat(),
- OFF_CENTER_STARTING_BOUNDS.bottom.toFloat())
+ PointF(
+ OFF_CENTER_STARTING_BOUNDS.right.toFloat(),
+ OFF_CENTER_STARTING_BOUNDS.bottom.toFloat()
+ )
val repositionTaskBounds = Rect(OFF_CENTER_STARTING_BOUNDS)
// Increase height and width by STABLE_BOUNDS. Subtract by 5px so that it doesn't reach
// the disallowed drag area.
@@ -365,9 +428,11 @@ class DragPositioningCallbackUtilityTest {
val newY = STABLE_BOUNDS.bottom.toFloat() - offset
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
repositionTaskBounds, OFF_CENTER_STARTING_BOUNDS, STABLE_BOUNDS, delta,
- mockDisplayController, mockWindowDecoration)
+ mockDisplayController, mockWindowDecoration
+ )
assertThat(repositionTaskBounds.width()).isGreaterThan(STABLE_BOUNDS.right)
assertThat(repositionTaskBounds.height()).isGreaterThan(STABLE_BOUNDS.bottom)
}
@@ -375,10 +440,12 @@ class DragPositioningCallbackUtilityTest {
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
fun testChangeBoundsInDesktopMode_windowSizeExceedsStableBounds_shouldBeLimitedToDisplaySize() {
- doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) }
+ doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(mockContext) }
val startingPoint =
- PointF(OFF_CENTER_STARTING_BOUNDS.right.toFloat(),
- OFF_CENTER_STARTING_BOUNDS.bottom.toFloat())
+ PointF(
+ OFF_CENTER_STARTING_BOUNDS.right.toFloat(),
+ OFF_CENTER_STARTING_BOUNDS.bottom.toFloat()
+ )
val repositionTaskBounds = Rect(OFF_CENTER_STARTING_BOUNDS)
// Increase height and width by STABLE_BOUNDS. Subtract by 5px so that it doesn't reach
// the disallowed drag area.
@@ -387,9 +454,11 @@ class DragPositioningCallbackUtilityTest {
val newY = STABLE_BOUNDS.bottom.toFloat() - offset
val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
- DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+ DragPositioningCallbackUtility.changeBounds(
+ CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
repositionTaskBounds, OFF_CENTER_STARTING_BOUNDS, STABLE_BOUNDS, delta,
- mockDisplayController, mockWindowDecoration)
+ mockDisplayController, mockWindowDecoration
+ )
assertThat(repositionTaskBounds.width()).isLessThan(STABLE_BOUNDS.right)
assertThat(repositionTaskBounds.height()).isLessThan(STABLE_BOUNDS.bottom)
}
@@ -423,7 +492,8 @@ class DragPositioningCallbackUtilityTest {
DISPLAY_BOUNDS.left,
DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT,
DISPLAY_BOUNDS.right,
- DISPLAY_BOUNDS.bottom)
+ DISPLAY_BOUNDS.bottom
+ )
private val STABLE_BOUNDS = Rect(
DISPLAY_BOUNDS.left,
DISPLAY_BOUNDS.top,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
index 2ce59ff0a4a9..3a3e965b625e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositionerTest.kt
@@ -678,6 +678,7 @@ class FluidResizeTaskPositionerTest : ShellTestCase() {
CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM)
val rectAfterDrag = Rect(STARTING_BOUNDS)
rectAfterDrag.right += 2000
+ rectAfterDrag.bottom = STABLE_BOUNDS_LANDSCAPE.bottom
// First drag; we should fetch stable bounds.
verify(mockDisplayLayout, Mockito.times(1)).getStableBounds(any())
verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
@@ -705,8 +706,8 @@ class FluidResizeTaskPositionerTest : ShellTestCase() {
STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat(),
STARTING_BOUNDS.right.toFloat() + 2000, STARTING_BOUNDS.bottom.toFloat() + 2000,
CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM)
- rectAfterDrag.right -= 2000
- rectAfterDrag.bottom += 2000
+ rectAfterDrag.right = STABLE_BOUNDS_PORTRAIT.right
+ rectAfterDrag.bottom = STARTING_BOUNDS.bottom + 2000
verify(mockShellTaskOrganizer).applyTransaction(argThat { wct ->
return@argThat wct.changes.any { (token, change) ->
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
index 08a6e1ba676b..6ae16edaf3df 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
@@ -372,6 +372,7 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM)
val rectAfterDrag = Rect(STARTING_BOUNDS)
rectAfterDrag.right += 2000
+ rectAfterDrag.bottom = STABLE_BOUNDS_LANDSCAPE.bottom
// First drag; we should fetch stable bounds.
verify(mockDisplayLayout, times(1)).getStableBounds(any())
verify(mockTransitions).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
@@ -396,8 +397,8 @@ class VeiledResizeTaskPositionerTest : ShellTestCase() {
performDrag(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat(),
STARTING_BOUNDS.right.toFloat() + 2000, STARTING_BOUNDS.bottom.toFloat() + 2000,
CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM)
- rectAfterDrag.right -= 2000
- rectAfterDrag.bottom += 2000
+ rectAfterDrag.right = STABLE_BOUNDS_PORTRAIT.right
+ rectAfterDrag.bottom = STARTING_BOUNDS.bottom + 2000
verify(mockTransitions).startTransition(eq(TRANSIT_CHANGE), argThat { wct ->
return@argThat wct.changes.any { (token, change) ->
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 822a387351e3..0fa31c7a832e 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -107,7 +107,7 @@ AssetManager2::AssetManager2(ApkAssetsList apk_assets, const ResTable_config& co
}
AssetManager2::AssetManager2() {
- configurations_.resize(1);
+ configurations_.emplace_back();
}
bool AssetManager2::SetApkAssets(ApkAssetsList apk_assets, bool invalidate_caches) {
@@ -438,8 +438,8 @@ bool AssetManager2::ContainsAllocatedTable() const {
return false;
}
-void AssetManager2::SetConfigurations(std::vector<ResTable_config> configurations,
- bool force_refresh) {
+void AssetManager2::SetConfigurations(std::span<const ResTable_config> configurations,
+ bool force_refresh) {
int diff = 0;
if (force_refresh) {
diff = -1;
@@ -452,8 +452,10 @@ void AssetManager2::SetConfigurations(std::vector<ResTable_config> configuration
}
}
}
- configurations_ = std::move(configurations);
-
+ configurations_.clear();
+ for (auto&& config : configurations) {
+ configurations_.emplace_back(config);
+ }
if (diff) {
RebuildFilterList();
InvalidateCaches(static_cast<uint32_t>(diff));
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index ac46bc5c179f..0fdeefa09e26 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -32,6 +32,7 @@
#include "androidfw/AssetManager.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/Util.h"
+#include "ftl/small_vector.h"
namespace android {
@@ -159,9 +160,10 @@ class AssetManager2 {
// Sets/resets the configuration for this AssetManager. This will cause all
// caches that are related to the configuration change to be invalidated.
- void SetConfigurations(std::vector<ResTable_config> configurations, bool force_refresh = false);
+ void SetConfigurations(std::span<const ResTable_config> configurations,
+ bool force_refresh = false);
- inline const std::vector<ResTable_config>& GetConfigurations() const {
+ std::span<const ResTable_config> GetConfigurations() const {
return configurations_;
}
@@ -470,13 +472,13 @@ class AssetManager2 {
// An array mapping package ID to index into package_groups. This keeps the lookup fast
// without taking too much memory.
- std::array<uint8_t, std::numeric_limits<uint8_t>::max() + 1> package_ids_;
+ std::array<uint8_t, std::numeric_limits<uint8_t>::max() + 1> package_ids_ = {};
- uint32_t default_locale_;
+ uint32_t default_locale_ = 0;
// The current configurations set for this AssetManager. When this changes, cached resources
// may need to be purged.
- std::vector<ResTable_config> configurations_;
+ ftl::SmallVector<ResTable_config, 1> configurations_;
// Cached set of bags. These are cached because they can inherit keys from parent bags,
// which involves some calculation.
diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp
index c62f095e9dac..3f228841f6ba 100644
--- a/libs/androidfw/tests/AssetManager2_test.cpp
+++ b/libs/androidfw/tests/AssetManager2_test.cpp
@@ -113,7 +113,7 @@ TEST_F(AssetManager2Test, FindsResourceFromSingleApkAssets) {
desired_config.language[1] = 'e';
AssetManager2 assetmanager;
- assetmanager.SetConfigurations({desired_config});
+ assetmanager.SetConfigurations({{desired_config}});
assetmanager.SetApkAssets({basic_assets_});
auto value = assetmanager.GetResource(basic::R::string::test1);
@@ -137,7 +137,7 @@ TEST_F(AssetManager2Test, FindsResourceFromMultipleApkAssets) {
desired_config.language[1] = 'e';
AssetManager2 assetmanager;
- assetmanager.SetConfigurations({desired_config});
+ assetmanager.SetConfigurations({{desired_config}});
assetmanager.SetApkAssets({basic_assets_, basic_de_fr_assets_});
auto value = assetmanager.GetResource(basic::R::string::test1);
@@ -466,10 +466,10 @@ TEST_F(AssetManager2Test, ResolveDeepIdReference) {
TEST_F(AssetManager2Test, DensityOverride) {
AssetManager2 assetmanager;
assetmanager.SetApkAssets({basic_assets_, basic_xhdpi_assets_, basic_xxhdpi_assets_});
- assetmanager.SetConfigurations({{
+ assetmanager.SetConfigurations({{{
.density = ResTable_config::DENSITY_XHIGH,
.sdkVersion = 21,
- }});
+ }}});
auto value = assetmanager.GetResource(basic::R::string::density, false /*may_be_bag*/);
ASSERT_TRUE(value.has_value());
@@ -721,7 +721,7 @@ TEST_F(AssetManager2Test, GetLastPathWithoutEnablingReturnsEmpty) {
ResTable_config desired_config;
AssetManager2 assetmanager;
- assetmanager.SetConfigurations({desired_config});
+ assetmanager.SetConfigurations({{desired_config}});
assetmanager.SetApkAssets({basic_assets_});
assetmanager.SetResourceResolutionLoggingEnabled(false);
@@ -736,7 +736,7 @@ TEST_F(AssetManager2Test, GetLastPathWithoutResolutionReturnsEmpty) {
ResTable_config desired_config;
AssetManager2 assetmanager;
- assetmanager.SetConfigurations({desired_config});
+ assetmanager.SetConfigurations({{desired_config}});
assetmanager.SetApkAssets({basic_assets_});
auto result = assetmanager.GetLastResourceResolution();
@@ -751,7 +751,7 @@ TEST_F(AssetManager2Test, GetLastPathWithSingleApkAssets) {
AssetManager2 assetmanager;
assetmanager.SetResourceResolutionLoggingEnabled(true);
- assetmanager.SetConfigurations({desired_config});
+ assetmanager.SetConfigurations({{desired_config}});
assetmanager.SetApkAssets({basic_assets_});
auto value = assetmanager.GetResource(basic::R::string::test1);
@@ -774,7 +774,7 @@ TEST_F(AssetManager2Test, GetLastPathWithMultipleApkAssets) {
AssetManager2 assetmanager;
assetmanager.SetResourceResolutionLoggingEnabled(true);
- assetmanager.SetConfigurations({desired_config});
+ assetmanager.SetConfigurations({{desired_config}});
assetmanager.SetApkAssets({basic_assets_, basic_de_fr_assets_});
auto value = assetmanager.GetResource(basic::R::string::test1);
@@ -796,7 +796,7 @@ TEST_F(AssetManager2Test, GetLastPathAfterDisablingReturnsEmpty) {
AssetManager2 assetmanager;
assetmanager.SetResourceResolutionLoggingEnabled(true);
- assetmanager.SetConfigurations({desired_config});
+ assetmanager.SetConfigurations({{desired_config}});
assetmanager.SetApkAssets({basic_assets_});
auto value = assetmanager.GetResource(basic::R::string::test1);
@@ -817,7 +817,7 @@ TEST_F(AssetManager2Test, GetOverlayablesToString) {
AssetManager2 assetmanager;
assetmanager.SetResourceResolutionLoggingEnabled(true);
- assetmanager.SetConfigurations({desired_config});
+ assetmanager.SetConfigurations({{desired_config}});
assetmanager.SetApkAssets({overlayable_assets_});
const auto map = assetmanager.GetOverlayableMapForPackage(0x7f);
diff --git a/libs/androidfw/tests/BenchmarkHelpers.cpp b/libs/androidfw/tests/BenchmarkHelpers.cpp
index e3fc0a0a4e68..ec2abb84a5d5 100644
--- a/libs/androidfw/tests/BenchmarkHelpers.cpp
+++ b/libs/androidfw/tests/BenchmarkHelpers.cpp
@@ -66,7 +66,7 @@ void GetResourceBenchmark(const std::vector<std::string>& paths, const ResTable_
AssetManager2 assetmanager;
assetmanager.SetApkAssets(apk_assets);
if (config != nullptr) {
- assetmanager.SetConfigurations({*config});
+ assetmanager.SetConfigurations({{{*config}}});
}
while (state.KeepRunning()) {
diff --git a/libs/androidfw/tests/Theme_test.cpp b/libs/androidfw/tests/Theme_test.cpp
index 181d1411fb91..afcb0c1ad964 100644
--- a/libs/androidfw/tests/Theme_test.cpp
+++ b/libs/androidfw/tests/Theme_test.cpp
@@ -260,7 +260,7 @@ TEST_F(ThemeTest, ThemeRebase) {
ResTable_config night{};
night.uiMode = ResTable_config::UI_MODE_NIGHT_YES;
night.version = 8u;
- am_night.SetConfigurations({night});
+ am_night.SetConfigurations({{night}});
auto theme = am.NewTheme();
{
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index 03372b206f48..0605dbe130d3 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -914,7 +914,8 @@ public final class CardEmulation {
* otherwise a call to this method will fail and throw {@link SecurityException}.
* @param activity The Activity that requests NFC controller routing table to be changed.
* @param protocol ISO-DEP route destination, which can be "DH" or "UICC" or "ESE".
- * @param technology Tech-A, Tech-B route destination, which can be "DH" or "UICC" or "ESE".
+ * @param technology Tech-A, Tech-B and Tech-F route destination, which can be "DH" or "UICC"
+ * or "ESE".
* @throws SecurityException if the caller is not the preferred NFC service
* @throws IllegalArgumentException if the activity is not resumed or the caller is not in the
* foreground, or both protocol route and technology route are null.
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
index 69ef718200b9..0d4ce5be7b0e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
@@ -53,9 +53,11 @@ import androidx.annotation.Nullable;
import com.android.settingslib.R;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Comparator;
import java.util.Objects;
/**
@@ -88,6 +90,33 @@ public class ZenMode implements Parcelable {
.allowPriorityChannels(false)
.build();
+ private static final Comparator<Integer> PRIORITIZED_TYPE_COMPARATOR = new Comparator<>() {
+
+ private static final ImmutableList</* @AutomaticZenRule.Type */ Integer>
+ PRIORITIZED_TYPES = ImmutableList.of(
+ AutomaticZenRule.TYPE_BEDTIME,
+ AutomaticZenRule.TYPE_DRIVING);
+
+ @Override
+ public int compare(Integer first, Integer second) {
+ if (PRIORITIZED_TYPES.contains(first) && PRIORITIZED_TYPES.contains(second)) {
+ return PRIORITIZED_TYPES.indexOf(first) - PRIORITIZED_TYPES.indexOf(second);
+ } else if (PRIORITIZED_TYPES.contains(first)) {
+ return -1;
+ } else if (PRIORITIZED_TYPES.contains(second)) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ };
+
+ // Manual DND first, Bedtime/Driving, then alphabetically.
+ static final Comparator<ZenMode> PRIORITIZING_COMPARATOR = Comparator
+ .comparing(ZenMode::isManualDnd).reversed()
+ .thenComparing(ZenMode::getType, PRIORITIZED_TYPE_COMPARATOR)
+ .thenComparing(ZenMode::getName);
+
public enum Status {
ENABLED,
ENABLED_AND_ACTIVE,
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
index 64e503b323b8..c8a12f481c6e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
@@ -34,7 +34,6 @@ import com.android.settingslib.R;
import java.time.Duration;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.List;
import java.util.Map;
@@ -92,10 +91,7 @@ public class ZenModesBackend {
}
}
- // Manual DND first, then alphabetically.
- modes.sort(Comparator.comparing(ZenMode::isManualDnd).reversed()
- .thenComparing(ZenMode::getName));
-
+ modes.sort(ZenMode.PRIORITIZING_COMPARATOR);
return modes;
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
index f46424773fef..bab4bc3b0bf5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
@@ -16,6 +16,12 @@
package com.android.settingslib.notification.modes;
+import static android.app.AutomaticZenRule.TYPE_BEDTIME;
+import static android.app.AutomaticZenRule.TYPE_DRIVING;
+import static android.app.AutomaticZenRule.TYPE_IMMERSIVE;
+import static android.app.AutomaticZenRule.TYPE_OTHER;
+import static android.app.AutomaticZenRule.TYPE_THEATER;
+import static android.app.AutomaticZenRule.TYPE_UNKNOWN;
import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
@@ -38,6 +44,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
+import java.util.ArrayList;
+import java.util.List;
+
@RunWith(RobolectricTestRunner.class)
public class ZenModeTest {
@@ -46,7 +55,7 @@ public class ZenModeTest {
private static final AutomaticZenRule ZEN_RULE =
new AutomaticZenRule.Builder("Driving", Uri.parse("drive"))
.setPackage("com.some.driving.thing")
- .setType(AutomaticZenRule.TYPE_DRIVING)
+ .setType(TYPE_DRIVING)
.setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
.setZenPolicy(ZEN_POLICY)
.build();
@@ -226,6 +235,28 @@ public class ZenModeTest {
}
@Test
+ public void comparator_prioritizes() {
+ ZenMode manualDnd = TestModeBuilder.MANUAL_DND_INACTIVE;
+ ZenMode driving1 = new TestModeBuilder().setName("b1").setType(TYPE_DRIVING).build();
+ ZenMode driving2 = new TestModeBuilder().setName("b2").setType(TYPE_DRIVING).build();
+ ZenMode bedtime1 = new TestModeBuilder().setName("c1").setType(TYPE_BEDTIME).build();
+ ZenMode bedtime2 = new TestModeBuilder().setName("c2").setType(TYPE_BEDTIME).build();
+ ZenMode other = new TestModeBuilder().setName("a1").setType(TYPE_OTHER).build();
+ ZenMode immersive = new TestModeBuilder().setName("a2").setType(TYPE_IMMERSIVE).build();
+ ZenMode unknown = new TestModeBuilder().setName("a3").setType(TYPE_UNKNOWN).build();
+ ZenMode theater = new TestModeBuilder().setName("a4").setType(TYPE_THEATER).build();
+
+ ArrayList<ZenMode> list = new ArrayList<>(List.of(other, theater, bedtime1, unknown,
+ driving2, manualDnd, driving1, bedtime2, immersive));
+ list.sort(ZenMode.PRIORITIZING_COMPARATOR);
+
+ assertThat(list)
+ .containsExactly(manualDnd, bedtime1, bedtime2, driving1, driving2, other,
+ immersive, unknown, theater)
+ .inOrder();
+ }
+
+ @Test
public void writeToParcel_equals() {
assertUnparceledIsEqualToOriginal("example",
new ZenMode("id", ZEN_RULE, zenConfigRuleFor(ZEN_RULE, false)));
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index 75f8384321b0..3e62b7b2cf6e 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -32,6 +32,7 @@ android_library {
"unsupportedappusage",
],
static_libs: [
+ "aconfig_device_paths_java",
"aconfig_new_storage_flags_lib",
"aconfigd_java_utils",
"aconfig_demo_flags_java_lib",
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index 8b0772bb644d..121bd3e6e771 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -20,8 +20,10 @@ import static android.provider.Settings.Config.SYNC_DISABLED_MODE_NONE;
import static android.provider.Settings.Config.SYNC_DISABLED_MODE_PERSISTENT;
import static android.provider.Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT;
-import android.aconfig.Aconfig.parsed_flag;
-import android.aconfig.Aconfig.parsed_flags;
+import android.aconfig.DeviceProtos;
+import android.aconfig.nano.Aconfig;
+import android.aconfig.nano.Aconfig.parsed_flag;
+import android.aconfig.nano.Aconfig.parsed_flags;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.AttributionSource;
@@ -42,7 +44,6 @@ import android.provider.Settings.Config.SyncDisabledMode;
import android.provider.UpdatableDeviceConfigServiceReadiness;
import android.util.Slog;
-import com.android.internal.pm.pkg.component.AconfigFlags;
import com.android.internal.util.FastPrintWriter;
import java.io.File;
@@ -136,11 +137,8 @@ public final class DeviceConfigService extends Binder {
continue;
}
- for (parsed_flag flag : parsedFlags.getParsedFlagList()) {
- String namespace = flag.getNamespace();
- String packageName = flag.getPackage();
- String name = flag.getName();
- nameSet.add(namespace + "/" + packageName + "." + name);
+ for (parsed_flag flag : parsedFlags.parsedFlag) {
+ nameSet.add(flag.namespace + "/" + flag.package_ + "." + flag.name);
}
}
} catch (IOException e) {
@@ -169,6 +167,7 @@ public final class DeviceConfigService extends Binder {
static final class MyShellCommand extends ShellCommand {
final SettingsProvider mProvider;
+ private HashMap<String, parsed_flag> mAconfigParsedFlags;
enum CommandVerb {
GET,
@@ -186,6 +185,51 @@ public final class DeviceConfigService extends Binder {
MyShellCommand(SettingsProvider provider) {
mProvider = provider;
+
+ if (Flags.checkRootAndReadOnly()) {
+ List<parsed_flag> parsedFlags;
+ try {
+ parsedFlags = DeviceProtos.loadAndParseFlagProtos();
+ } catch (IOException e) {
+ throw new IllegalStateException("failed to parse aconfig protos");
+ }
+
+ mAconfigParsedFlags = new HashMap();
+ for (parsed_flag flag : parsedFlags) {
+ mAconfigParsedFlags.put(flag.package_ + "." + flag.name, flag);
+ }
+ }
+ }
+
+ /**
+ * Return true if a flag is aconfig.
+ */
+ private boolean isAconfigFlag(String name) {
+ return mAconfigParsedFlags.get(name) != null;
+ }
+
+ /**
+ * Return true if a flag is both aconfig and read-only.
+ *
+ * @return true if a flag is both aconfig and read-only
+ */
+ private boolean isReadOnly(String name) {
+ parsed_flag flag = mAconfigParsedFlags.get(name);
+ if (flag != null) {
+ if (flag.permission == Aconfig.READ_ONLY) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return true if the calling process is root.
+ *
+ * @return true if a flag is aconfig, and the calling process is root
+ */
+ private boolean isRoot() {
+ return Binder.getCallingUid() == Process.ROOT_UID;
}
public static HashMap<String, String> getAllFlags(IContentProvider provider) {
@@ -414,21 +458,71 @@ public final class DeviceConfigService extends Binder {
pout.println(DeviceConfig.getProperty(namespace, key));
break;
case PUT:
+ if (Flags.checkRootAndReadOnly()) {
+ if (isAconfigFlag(key)) {
+ if (!isRoot()) {
+ pout.println("Error: must be root to write aconfig flag");
+ break;
+ }
+
+ if (isReadOnly(key)) {
+ pout.println("Error: cannot write read-only flag");
+ break;
+ }
+ }
+ }
+
DeviceConfig.setProperty(namespace, key, value, makeDefault);
break;
case OVERRIDE:
- AconfigFlags.Permission permission =
- (new AconfigFlags()).getFlagPermission(key);
- if (permission == AconfigFlags.Permission.READ_ONLY) {
- pout.println("cannot override read-only flag " + key);
- } else {
- DeviceConfig.setLocalOverride(namespace, key, value);
+ if (Flags.checkRootAndReadOnly()) {
+ if (isAconfigFlag(key)) {
+ if (!isRoot()) {
+ pout.println("Error: must be root to write aconfig flag");
+ break;
+ }
+
+ if (isReadOnly(key)) {
+ pout.println("Error: cannot write read-only flag");
+ break;
+ }
+ }
}
+
+ DeviceConfig.setLocalOverride(namespace, key, value);
break;
case CLEAR_OVERRIDE:
+ if (Flags.checkRootAndReadOnly()) {
+ if (isAconfigFlag(key)) {
+ if (!isRoot()) {
+ pout.println("Error: must be root to write aconfig flag");
+ break;
+ }
+
+ if (isReadOnly(key)) {
+ pout.println("Error: cannot write read-only flag");
+ break;
+ }
+ }
+ }
+
DeviceConfig.clearLocalOverride(namespace, key);
break;
case DELETE:
+ if (Flags.checkRootAndReadOnly()) {
+ if (isAconfigFlag(key)) {
+ if (!isRoot()) {
+ pout.println("Error: must be root to write aconfig flag");
+ break;
+ }
+
+ if (isReadOnly(key)) {
+ pout.println("Error: cannot write read-only flag");
+ break;
+ }
+ }
+ }
+
pout.println(delete(iprovider, namespace, key)
? "Successfully deleted " + key + " from " + namespace
: "Failed to delete " + key + " from " + namespace);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig b/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
index b1e6d6650226..006e644b2ac7 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
+++ b/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
@@ -70,3 +70,14 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "check_root_and_read_only"
+ namespace: "core_experiments_team_internal"
+ description: "Check root and aconfig flag permissions in adb shell device_config commands."
+ bug: "342636474"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
index 069113b378da..163b35596c1b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/bouncer/ui/composable/PatternBouncer.kt
@@ -511,7 +511,7 @@ private const val DOT_DIAMETER_DP = 14
private const val SELECTED_DOT_DIAMETER_DP = (DOT_DIAMETER_DP * 1.5).toInt()
private const val SELECTED_DOT_REACTION_ANIMATION_DURATION_MS = 83
private const val SELECTED_DOT_RETRACT_ANIMATION_DURATION_MS = 750
-private const val LINE_STROKE_WIDTH_DP = DOT_DIAMETER_DP
+private const val LINE_STROKE_WIDTH_DP = 22
private const val FAILURE_ANIMATION_DOT_DIAMETER_DP = (DOT_DIAMETER_DP * 0.81f).toInt()
private const val FAILURE_ANIMATION_DOT_SHRINK_ANIMATION_DURATION_MS = 50
private const val FAILURE_ANIMATION_DOT_SHRINK_STAGGER_DELAY_MS = 33
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index 7472d818d71a..91a88bc7aa97 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -170,7 +170,6 @@ import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
import com.android.systemui.communal.util.DensityUtils.Companion.adjustedDp
-import com.android.systemui.communal.util.DensityUtils.Companion.scalingAdjustment
import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView
import com.android.systemui.communal.widgets.WidgetConfigurator
import com.android.systemui.res.R
@@ -478,8 +477,7 @@ fun CommunalHub(
}
val hubDimensions: Dimensions
- @Composable
- get() = Dimensions(LocalContext.current, LocalConfiguration.current, LocalDensity.current)
+ @Composable get() = Dimensions(LocalContext.current, LocalConfiguration.current)
@Composable
private fun DisclaimerBottomSheetContent(onButtonClicked: () -> Unit) {
@@ -1288,8 +1286,9 @@ fun DisabledWidgetPlaceholder(
modifier =
modifier
.background(
- MaterialTheme.colorScheme.surfaceVariant,
- RoundedCornerShape(dimensionResource(system_app_widget_background_radius))
+ color = MaterialTheme.colorScheme.surfaceVariant,
+ shape =
+ RoundedCornerShape(dimensionResource(system_app_widget_background_radius))
)
.clickable(
enabled = !viewModel.isEditMode,
@@ -1325,10 +1324,8 @@ fun PendingWidgetPlaceholder(
Column(
modifier =
modifier.background(
- MaterialTheme.colorScheme.surfaceVariant,
- RoundedCornerShape(
- dimensionResource(system_app_widget_background_radius) * scalingAdjustment
- )
+ color = MaterialTheme.colorScheme.surfaceVariant,
+ shape = RoundedCornerShape(dimensionResource(system_app_widget_background_radius))
),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
@@ -1514,21 +1511,24 @@ data class ContentPaddingInPx(val start: Float, val top: Float) {
fun toOffset(): Offset = Offset(start, top)
}
-class Dimensions(val context: Context, val config: Configuration, val density: Density) {
+class Dimensions(val context: Context, val config: Configuration) {
val GridTopSpacing: Dp
get() {
- if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
- return 114.adjustedDp
- } else {
- val windowMetrics =
- WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
- val screenHeight = with(density) { windowMetrics.bounds.height().adjustedDp }
-
- return (screenHeight - CardHeightFull) / 2
- }
+ val result =
+ if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ 114.dp
+ } else {
+ val windowMetrics =
+ WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
+ val density = context.resources.displayMetrics.density
+ val screenHeight = (windowMetrics.bounds.height() / density).dp
+ ((screenHeight - CardHeightFull) / 2)
+ }
+ return result
}
- val GridHeight = CardHeightFull + GridTopSpacing
+ val GridHeight: Dp
+ get() = CardHeightFull + GridTopSpacing
companion object {
val CardHeightFull
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
index 08ee60204178..a3f40d47cc3f 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
@@ -18,10 +18,17 @@
package com.android.systemui.shared.quickaffordance.shared.model
object KeyguardPreviewConstants {
+ const val MESSAGE_ID_DEFAULT_PREVIEW = 707
const val MESSAGE_ID_HIDE_SMART_SPACE = 1111
- const val KEY_HIDE_SMART_SPACE = "hide_smart_space"
+ const val MESSAGE_ID_PREVIEW_QUICK_AFFORDANCE_SELECTED = 1988
const val MESSAGE_ID_SLOT_SELECTED = 1337
- const val KEY_SLOT_ID = "slot_id"
- const val KEY_INITIALLY_SELECTED_SLOT_ID = "initially_selected_slot_id"
+ const val MESSAGE_ID_START_CUSTOMIZING_QUICK_AFFORDANCES = 214
+
+ const val KEY_HIDE_SMART_SPACE = "hide_smart_space"
const val KEY_HIGHLIGHT_QUICK_AFFORDANCES = "highlight_quick_affordances"
+ const val KEY_INITIALLY_SELECTED_SLOT_ID = "initially_selected_slot_id"
+ const val KEY_QUICK_AFFORDANCE_ID = "quick_affordance_id"
+ const val KEY_SLOT_ID = "slot_id"
+
+ const val KEYGUARD_QUICK_AFFORDANCE_ID_NONE = "none"
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
index b83ab7ef0c1b..c1615253804c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
@@ -430,6 +430,22 @@ class BouncerMessageViewModelTest : SysuiTestCase() {
.isEqualTo("Can’t unlock with face. Too many attempts.")
}
+ @Test
+ fun startLockdownCountdown_onActivated() =
+ testScope.runTest {
+ val bouncerMessage by collectLastValue(underTest.message)
+ val lockoutSeconds = 200 * 1000 // 200 second lockout
+ kosmos.fakeAuthenticationRepository.setAuthenticationMethod(Pin)
+ kosmos.fakeAuthenticationRepository.reportLockoutStarted(lockoutSeconds)
+ runCurrent()
+
+ assertThat(bouncerMessage?.text).isEqualTo("Try again in 200 seconds.")
+ advanceTimeBy(100.seconds)
+ assertThat(bouncerMessage?.text).isEqualTo("Try again in 100 seconds.")
+ advanceTimeBy(101.seconds)
+ assertThat(bouncerMessage?.text).isEqualTo("Enter PIN")
+ }
+
private fun TestScope.verifyMessagesForAuthFlags(
vararg authFlagToMessagePair: Pair<Int, Pair<String, String?>>
) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt
index d6712f09cd4e..c5518b029bc1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractorTest.kt
@@ -53,6 +53,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.se
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
+import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -78,6 +79,7 @@ class CommunalSceneTransitionInteractorTest : SysuiTestCase() {
private val underTest by lazy { kosmos.communalSceneTransitionInteractor }
private val keyguardTransitionRepository by lazy { kosmos.realKeyguardTransitionRepository }
+ private val keyguardRepository by lazy { kosmos.fakeKeyguardRepository }
private val ownerName = CommunalSceneTransitionInteractor::class.java.simpleName
private val progress = MutableSharedFlow<Float>()
@@ -789,4 +791,47 @@ class CommunalSceneTransitionInteractorTest : SysuiTestCase() {
)
)
}
+
+ /** Verifies that we correctly transition to GONE after keyguard goes away */
+ @Test
+ fun transition_to_blank_after_unlock_should_go_to_gone() =
+ testScope.runTest {
+ keyguardRepository.setKeyguardShowing(true)
+ sceneTransitions.value = Idle(CommunalScenes.Communal)
+
+ val currentStep by collectLastValue(keyguardTransitionRepository.transitions)
+
+ assertThat(currentStep)
+ .isEqualTo(
+ TransitionStep(
+ from = LOCKSCREEN,
+ to = GLANCEABLE_HUB,
+ transitionState = FINISHED,
+ value = 1f,
+ ownerName = ownerName,
+ )
+ )
+
+ // Keyguard starts exiting after a while, then fully exits after some time.
+ advanceTimeBy(1.seconds)
+ keyguardRepository.setKeyguardGoingAway(true)
+ advanceTimeBy(2.seconds)
+ keyguardRepository.setKeyguardGoingAway(false)
+ keyguardRepository.setKeyguardShowing(false)
+ runCurrent()
+
+ // We snap to the blank scene as a result of keyguard going away.
+ sceneTransitions.value = Idle(CommunalScenes.Blank)
+
+ assertThat(currentStep)
+ .isEqualTo(
+ TransitionStep(
+ from = GLANCEABLE_HUB,
+ to = GONE,
+ transitionState = FINISHED,
+ value = 1f,
+ ownerName = ownerName,
+ )
+ )
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt
deleted file mode 100644
index 50fdb31b0414..000000000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal.widgets
-
-import android.app.Activity
-import android.app.Application.ActivityLifecycleCallbacks
-import android.os.Bundle
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.kotlin.argumentCaptor
-import org.mockito.kotlin.clearInvocations
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.never
-import org.mockito.kotlin.verify
-
-@ExperimentalCoroutinesApi
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class EditWidgetsActivityControllerTest : SysuiTestCase() {
- @Test
- fun activityLifecycle_stoppedWhenNotWaitingForResult() {
- val activity = mock<Activity>()
- val controller = EditWidgetsActivity.ActivityController(activity)
-
- val callbackCapture = argumentCaptor<ActivityLifecycleCallbacks>()
- verify(activity).registerActivityLifecycleCallbacks(callbackCapture.capture())
-
- callbackCapture.lastValue.onActivityStopped(activity)
-
- verify(activity).finish()
- }
-
- @Test
- fun activityLifecycle_notStoppedWhenNotWaitingForResult() {
- val activity = mock<Activity>()
- val controller = EditWidgetsActivity.ActivityController(activity)
-
- val callbackCapture = argumentCaptor<ActivityLifecycleCallbacks>()
- verify(activity).registerActivityLifecycleCallbacks(callbackCapture.capture())
-
- controller.onWaitingForResult(true)
- callbackCapture.lastValue.onActivityStopped(activity)
-
- verify(activity, never()).finish()
- }
-
- @Test
- fun activityLifecycle_stoppedAfterResultReturned() {
- val activity = mock<Activity>()
- val controller = EditWidgetsActivity.ActivityController(activity)
-
- val callbackCapture = argumentCaptor<ActivityLifecycleCallbacks>()
- verify(activity).registerActivityLifecycleCallbacks(callbackCapture.capture())
-
- controller.onWaitingForResult(true)
- controller.onWaitingForResult(false)
- callbackCapture.lastValue.onActivityStopped(activity)
-
- verify(activity).finish()
- }
-
- @Test
- fun activityLifecycle_statePreservedThroughInstanceSave() {
- val activity = mock<Activity>()
- val bundle = Bundle(1)
-
- run {
- val controller = EditWidgetsActivity.ActivityController(activity)
- val callbackCapture = argumentCaptor<ActivityLifecycleCallbacks>()
- verify(activity).registerActivityLifecycleCallbacks(callbackCapture.capture())
-
- controller.onWaitingForResult(true)
- callbackCapture.lastValue.onActivitySaveInstanceState(activity, bundle)
- }
-
- clearInvocations(activity)
-
- run {
- val controller = EditWidgetsActivity.ActivityController(activity)
- val callbackCapture = argumentCaptor<ActivityLifecycleCallbacks>()
- verify(activity).registerActivityLifecycleCallbacks(callbackCapture.capture())
-
- callbackCapture.lastValue.onActivityCreated(activity, bundle)
- callbackCapture.lastValue.onActivityStopped(activity)
-
- verify(activity, never()).finish()
- }
- }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
index 400f736ba882..9c308a60d3f0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
@@ -25,15 +25,19 @@ import androidx.core.util.component1
import androidx.core.util.component2
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.keyguard.keyguardUpdateMonitor
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.domain.interactor.widgetTrampolineInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.backgroundCoroutineContext
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.testKosmos
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@@ -41,12 +45,14 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.eq
import org.mockito.kotlin.isNull
import org.mockito.kotlin.mock
import org.mockito.kotlin.refEq
import org.mockito.kotlin.verify
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class WidgetInteractionHandlerTest : SysuiTestCase() {
@@ -70,8 +76,10 @@ class WidgetInteractionHandlerTest : SysuiTestCase() {
underTest =
WidgetInteractionHandler(
applicationScope = applicationCoroutineScope,
+ uiBackgroundContext = backgroundCoroutineContext,
activityStarter = activityStarter,
communalSceneInteractor = communalSceneInteractor,
+ keyguardUpdateMonitor = keyguardUpdateMonitor,
logBuffer = logcatLogBuffer(),
widgetTrampolineInteractor = widgetTrampolineInteractor,
)
@@ -95,16 +103,21 @@ class WidgetInteractionHandlerTest : SysuiTestCase() {
// Verify that we set the state correctly
assertTrue(launching!!)
// Verify that we pass in a non-null Communal animation controller
+
+ val callbackCaptor = argumentCaptor<Runnable>()
verify(activityStarter)
.startPendingIntentMaybeDismissingKeyguard(
/* intent = */ eq(testIntent),
/* dismissShade = */ eq(false),
- /* intentSentUiThreadCallback = */ isNull(),
+ /* intentSentUiThreadCallback = */ callbackCaptor.capture(),
/* animationController = */ any<CommunalTransitionAnimatorController>(),
/* fillInIntent = */ refEq(fillInIntent),
/* extraOptions = */ refEq(activityOptions.toBundle()),
/* customMessage */ isNull(),
)
+ callbackCaptor.firstValue.run()
+ runCurrent()
+ verify(keyguardUpdateMonitor).awakenFromDream()
}
}
}
@@ -123,7 +136,7 @@ class WidgetInteractionHandlerTest : SysuiTestCase() {
.startPendingIntentMaybeDismissingKeyguard(
/* intent = */ eq(testIntent),
/* dismissShade = */ eq(false),
- /* intentSentUiThreadCallback = */ isNull(),
+ /* intentSentUiThreadCallback = */ any(),
/* animationController = */ isNull(),
/* fillInIntent = */ refEq(fillInIntent),
/* extraOptions = */ refEq(activityOptions.toBundle()),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index 8e109b4aab20..c85cd662dac6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -308,6 +308,15 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
)
}
+ @Test
+ fun getConfig() =
+ testScope.runTest {
+ assertThat(underTest.getConfig(FakeCustomizationProviderClient.AFFORDANCE_1))
+ .isEqualTo(config1)
+ assertThat(underTest.getConfig(FakeCustomizationProviderClient.AFFORDANCE_2))
+ .isEqualTo(config2)
+ }
+
private fun assertSelections(
observed: Map<String, List<KeyguardQuickAffordanceConfig>>?,
expected: Map<String, List<KeyguardQuickAffordanceConfig>>,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 75c0d3b60ecb..ad07c1c1b88f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -426,6 +426,64 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
}
@Test
+ fun quickAffordanceAlwaysVisible_withNonNullOverrideKeyguardQuickAffordanceId() =
+ testScope.runTest {
+ quickAccessWallet.setState(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ icon = ICON,
+ activationState = ActivationState.Active,
+ )
+ )
+ homeControls.setState(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ icon = ICON,
+ activationState = ActivationState.Active,
+ )
+ )
+
+ // The default case
+ val collectedValue =
+ collectLastValue(
+ underTest.quickAffordanceAlwaysVisible(
+ KeyguardQuickAffordancePosition.BOTTOM_START,
+ )
+ )
+ assertThat(collectedValue())
+ .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
+ val visibleModel = collectedValue() as KeyguardQuickAffordanceModel.Visible
+ assertThat(visibleModel.configKey)
+ .isEqualTo(
+ "${KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START}::${homeControls.key}"
+ )
+ assertThat(visibleModel.icon).isEqualTo(ICON)
+ assertThat(visibleModel.icon.contentDescription)
+ .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID))
+ assertThat(visibleModel.activationState).isEqualTo(ActivationState.Active)
+
+ // With override
+ val collectedValueWithOverride =
+ collectLastValue(
+ underTest.quickAffordanceAlwaysVisible(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ overrideQuickAffordanceId =
+ BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET,
+ )
+ )
+ assertThat(collectedValueWithOverride())
+ .isInstanceOf(KeyguardQuickAffordanceModel.Visible::class.java)
+ val visibleModelWithOverride =
+ collectedValueWithOverride() as KeyguardQuickAffordanceModel.Visible
+ assertThat(visibleModelWithOverride.configKey)
+ .isEqualTo(
+ "${KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START}::${quickAccessWallet.key}"
+ )
+ assertThat(visibleModelWithOverride.icon).isEqualTo(ICON)
+ assertThat(visibleModelWithOverride.icon.contentDescription)
+ .isEqualTo(ContentDescription.Resource(res = CONTENT_DESCRIPTION_RESOURCE_ID))
+ assertThat(visibleModelWithOverride.activationState).isEqualTo(ActivationState.Active)
+ }
+
+ @Test
fun select() =
testScope.runTest {
overrideResource(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
index 4d1dd1cce766..d9faa30cb072 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
@@ -32,6 +32,7 @@ import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription
@@ -45,6 +46,7 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+@FlakyTest(bugId = 360351805)
@SmallTest
@RunWith(AndroidJUnit4::class)
class DragAndDropTest : SysuiTestCase() {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index aee3ce052d78..9122528e5c11 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -328,6 +328,16 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
}
@Test
+ fun lockDeviceLocksDevice() =
+ testScope.runTest {
+ unlockDevice()
+ assertCurrentScene(Scenes.Gone)
+
+ lockDevice()
+ assertCurrentScene(Scenes.Lockscreen)
+ }
+
+ @Test
fun deviceGoesToSleep_switchesToLockscreen() =
testScope.runTest {
unlockDevice()
@@ -616,7 +626,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
assertWithMessage("The authentication method of $authMethod is not secure, cannot lock!")
.that(authMethod.isSecure)
.isTrue()
-
+ kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "")
runCurrent()
}
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f8303ea8e1c6..8a2e767a5a3c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -756,6 +756,8 @@
<string name="quick_settings_bluetooth_audio_sharing_button">Share audio</string>
<!-- QuickSettings: Bluetooth dialog audio sharing button text when sharing audio [CHAR LIMIT=50]-->
<string name="quick_settings_bluetooth_audio_sharing_button_sharing">Sharing audio</string>
+ <!-- QuickSettings: Bluetooth dialog audio sharing button text accessibility label. Used as part of the string "Double tap to enter audio sharing settings". [CHAR LIMIT=50]-->
+ <string name="quick_settings_bluetooth_audio_sharing_button_accessibility">enter audio sharing settings</string>
<!-- QuickSettings: Bluetooth secondary label for the battery level of a connected device [CHAR LIMIT=20]-->
<string name="quick_settings_bluetooth_secondary_label_battery_level"><xliff:g id="battery_level_as_percentage">%s</xliff:g> battery</string>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
index f4a1f0546135..e4b7b7e69c61 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuController.java
@@ -37,6 +37,7 @@ import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.accessibility.AccessibilityButtonModeObserver.AccessibilityButtonMode;
import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.settings.DisplayTracker;
import com.android.systemui.util.settings.SecureSettings;
@@ -61,6 +62,7 @@ public class AccessibilityFloatingMenuController implements
private final SecureSettings mSecureSettings;
private final DisplayTracker mDisplayTracker;
+ private final NavigationModeController mNavigationModeController;
@VisibleForTesting
IAccessibilityFloatingMenu mFloatingMenu;
private int mBtnMode;
@@ -106,7 +108,8 @@ public class AccessibilityFloatingMenuController implements
AccessibilityButtonModeObserver accessibilityButtonModeObserver,
KeyguardUpdateMonitor keyguardUpdateMonitor,
SecureSettings secureSettings,
- DisplayTracker displayTracker) {
+ DisplayTracker displayTracker,
+ NavigationModeController navigationModeController) {
mContext = context;
mWindowManager = windowManager;
mViewCaptureAwareWindowManager = viewCaptureAwareWindowManager;
@@ -117,6 +120,7 @@ public class AccessibilityFloatingMenuController implements
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mSecureSettings = secureSettings;
mDisplayTracker = displayTracker;
+ mNavigationModeController = navigationModeController;
mIsKeyguardVisible = false;
}
@@ -191,7 +195,8 @@ public class AccessibilityFloatingMenuController implements
final Context windowContext = mContext.createWindowContext(defaultDisplay,
TYPE_NAVIGATION_BAR_PANEL, /* options= */ null);
mFloatingMenu = new MenuViewLayerController(windowContext, mWindowManager,
- mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings);
+ mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings,
+ mNavigationModeController);
}
mFloatingMenu.show();
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
index f4b6bfbddbac..d62162b368fa 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -77,6 +77,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.util.Preconditions;
import com.android.systemui.Flags;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.res.R;
import com.android.systemui.util.settings.SecureSettings;
import com.android.wm.shell.bubbles.DismissViewUtils;
@@ -142,6 +143,8 @@ class MenuViewLayer extends FrameLayout implements
private boolean mIsNotificationShown;
private Optional<MenuEduTooltipView> mEduTooltipView = Optional.empty();
private BroadcastReceiver mNotificationActionReceiver;
+ private NavigationModeController mNavigationModeController;
+ private NavigationModeController.ModeChangedListener mNavigationModeChangedListender;
@IntDef({
LayerIndex.MENU_VIEW,
@@ -220,7 +223,8 @@ class MenuViewLayer extends FrameLayout implements
MenuViewModel menuViewModel,
MenuViewAppearance menuViewAppearance, MenuView menuView,
IAccessibilityFloatingMenu floatingMenu,
- SecureSettings secureSettings) {
+ SecureSettings secureSettings,
+ NavigationModeController navigationModeController) {
super(context);
// Simplifies the translation positioning and animations
@@ -253,6 +257,8 @@ class MenuViewLayer extends FrameLayout implements
mNotificationFactory = new MenuNotificationFactory(context);
mNotificationManager = context.getSystemService(NotificationManager.class);
mStatusBarManager = context.getSystemService(StatusBarManager.class);
+ mNavigationModeController = navigationModeController;
+ mNavigationModeChangedListender = (mode -> mMenuView.onPositionChanged());
if (Flags.floatingMenuDragToEdit()) {
mDragToInteractAnimationController = new DragToInteractAnimationController(
@@ -381,6 +387,7 @@ class MenuViewLayer extends FrameLayout implements
mMigrationTooltipObserver);
mMessageView.setUndoListener(view -> undo());
getContext().registerComponentCallbacks(this);
+ mNavigationModeController.addListener(mNavigationModeChangedListender);
}
@Override
@@ -396,6 +403,7 @@ class MenuViewLayer extends FrameLayout implements
mMigrationTooltipObserver);
mHandler.removeCallbacksAndMessages(/* token= */ null);
getContext().unregisterComponentCallbacks(this);
+ mNavigationModeController.removeListener(mNavigationModeChangedListender);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java
index 623536f0f928..cb96e7859fba 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerController.java
@@ -24,6 +24,7 @@ import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.util.settings.SecureSettings;
/**
@@ -37,7 +38,8 @@ class MenuViewLayerController implements IAccessibilityFloatingMenu {
MenuViewLayerController(Context context, WindowManager windowManager,
ViewCaptureAwareWindowManager viewCaptureAwareWindowManager,
- AccessibilityManager accessibilityManager, SecureSettings secureSettings) {
+ AccessibilityManager accessibilityManager, SecureSettings secureSettings,
+ NavigationModeController navigationModeController) {
mWindowManager = viewCaptureAwareWindowManager;
MenuViewModel menuViewModel = new MenuViewModel(
@@ -49,7 +51,8 @@ class MenuViewLayerController implements IAccessibilityFloatingMenu {
menuViewAppearance,
new MenuView(context, menuViewModel, menuViewAppearance, secureSettings),
this,
- secureSettings);
+ secureSettings,
+ navigationModeController);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
index a5c5beccefd9..f4e2b82f1773 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistDisclosure.java
@@ -33,6 +33,7 @@ import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import com.android.app.animation.Interpolators;
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
import com.android.systemui.res.R;
/**
@@ -40,16 +41,17 @@ import com.android.systemui.res.R;
*/
public class AssistDisclosure {
private final Context mContext;
- private final WindowManager mWm;
+ private final ViewCaptureAwareWindowManager mWm;
private final Handler mHandler;
private AssistDisclosureView mView;
private boolean mViewAdded;
- public AssistDisclosure(Context context, Handler handler) {
+ public AssistDisclosure(Context context, Handler handler,
+ ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) {
mContext = context;
mHandler = handler;
- mWm = mContext.getSystemService(WindowManager.class);
+ mWm = viewCaptureAwareWindowManager;
}
public void postShow() {
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index a67dcdb70b67..939d96e67f8f 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -25,6 +25,7 @@ import android.service.voice.VisualQueryAttentionResult;
import android.service.voice.VoiceInteractionSession;
import android.util.Log;
+import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
import com.android.internal.app.AssistUtils;
import com.android.internal.app.IVisualQueryDetectionAttentionListener;
import com.android.internal.app.IVisualQueryRecognitionStatusListener;
@@ -195,12 +196,13 @@ public class AssistManager {
SecureSettings secureSettings,
SelectedUserInteractor selectedUserInteractor,
ActivityManager activityManager,
- AssistInteractor interactor) {
+ AssistInteractor interactor,
+ ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) {
mContext = context;
mDeviceProvisionedController = controller;
mCommandQueue = commandQueue;
mAssistUtils = assistUtils;
- mAssistDisclosure = new AssistDisclosure(context, uiHandler);
+ mAssistDisclosure = new AssistDisclosure(context, uiHandler, viewCaptureAwareWindowManager);
mOverviewProxyService = overviewProxyService;
mPhoneStateMonitor = phoneStateMonitor;
mAssistLogger = assistLogger;
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractor.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractor.kt
new file mode 100644
index 000000000000..d69e41626bd6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractor.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth.qsdialog
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChangedBy
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.merge
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class BluetoothDeviceMetadataInteractor
+@Inject
+constructor(
+ deviceItemInteractor: DeviceItemInteractor,
+ private val bluetoothAdapter: BluetoothAdapter?,
+ private val logger: BluetoothTileDialogLogger,
+ @Background private val executor: Executor,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+) {
+ private fun metadataUpdateForDevice(bluetoothDevice: BluetoothDevice): Flow<Unit> =
+ conflatedCallbackFlow {
+ val metadataChangedListener =
+ BluetoothAdapter.OnMetadataChangedListener { device, key, value ->
+ when (key) {
+ BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY,
+ BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY,
+ BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY,
+ BluetoothDevice.METADATA_MAIN_BATTERY -> {
+ trySendWithFailureLogging(Unit, TAG, "onMetadataChanged")
+ logger.logBatteryChanged(device.address, key, value)
+ }
+ }
+ }
+ bluetoothAdapter?.addOnMetadataChangedListener(
+ bluetoothDevice,
+ executor,
+ metadataChangedListener
+ )
+ awaitClose {
+ bluetoothAdapter?.removeOnMetadataChangedListener(
+ bluetoothDevice,
+ metadataChangedListener
+ )
+ }
+ }
+
+ val metadataUpdate: Flow<Unit> =
+ deviceItemInteractor.deviceItemUpdate
+ .distinctUntilChangedBy { it.bluetoothDevices }
+ .flatMapLatest { items ->
+ items.bluetoothDevices.map { device -> metadataUpdateForDevice(device) }.merge()
+ }
+ .flowOn(backgroundDispatcher)
+
+ private companion object {
+ private const val TAG = "BluetoothDeviceMetadataInteractor"
+ private val List<DeviceItem>.bluetoothDevices: Set<BluetoothDevice>
+ get() =
+ flatMapTo(mutableSetOf()) { item ->
+ listOf(item.cachedBluetoothDevice.device) +
+ item.cachedBluetoothDevice.memberDevice.map { it.device }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
index 2808dbe669ab..7deea7335223 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogDelegate.kt
@@ -129,8 +129,26 @@ internal constructor(
getPairNewDeviceButton(dialog).setOnClickListener {
bluetoothTileDialogCallback.onPairNewDeviceClicked(it)
}
- getAudioSharingButtonView(dialog).setOnClickListener {
- bluetoothTileDialogCallback.onAudioSharingButtonClicked(it)
+ getAudioSharingButtonView(dialog).apply {
+ setOnClickListener { bluetoothTileDialogCallback.onAudioSharingButtonClicked(it) }
+ accessibilityDelegate =
+ object : AccessibilityDelegate() {
+ override fun onInitializeAccessibilityNodeInfo(
+ host: View,
+ info: AccessibilityNodeInfo
+ ) {
+ super.onInitializeAccessibilityNodeInfo(host, info)
+ info.addAction(
+ AccessibilityAction(
+ AccessibilityAction.ACTION_CLICK.id,
+ context.getString(
+ R.string
+ .quick_settings_bluetooth_audio_sharing_button_accessibility
+ )
+ )
+ )
+ }
+ }
}
getScrollViewContent(dialog).apply {
minimumHeight =
@@ -445,7 +463,6 @@ internal constructor(
internal companion object {
const val MIN_HEIGHT_CHANGE_INTERVAL_MS = 800L
- const val MAX_DEVICE_ITEM_ENTRY = 3
const val ACTION_BLUETOOTH_DEVICE_DETAILS =
"com.android.settings.BLUETOOTH_DEVICE_DETAIL_SETTINGS"
const val ACTION_PREVIOUSLY_CONNECTED_DEVICE =
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogLogger.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogLogger.kt
index 72312b87dc57..06116f0a21c3 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogLogger.kt
@@ -90,6 +90,18 @@ constructor(@BluetoothTileDialogLog private val logBuffer: LogBuffer) {
{ "ProfileConnectionStateChanged. address=$str1 state=$str2 profileId=$int1" }
)
+ fun logBatteryChanged(address: String, key: Int, value: ByteArray?) =
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = address
+ int1 = key
+ str2 = value?.toString() ?: ""
+ },
+ { "BatteryChanged. address=$str1 key=$int1 value=$str2" }
+ )
+
fun logDeviceFetch(status: JobStatus, trigger: DeviceFetchTrigger, duration: Long) =
logBuffer.log(
TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogRepository.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogRepository.kt
index 6e51915797cc..56b79d199e09 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogRepository.kt
@@ -24,7 +24,7 @@ import javax.inject.Inject
/** Repository to get CachedBluetoothDevices for the Bluetooth Dialog. */
@SysUISingleton
-internal class BluetoothTileDialogRepository
+class BluetoothTileDialogRepository
@Inject
constructor(
private val localBluetoothManager: LocalBluetoothManager?,
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
index 985b1588807b..8b2449aa1ffd 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
@@ -37,7 +37,6 @@ import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogDelegate.Compa
import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogDelegate.Companion.ACTION_BLUETOOTH_DEVICE_DETAILS
import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogDelegate.Companion.ACTION_PAIR_NEW_DEVICE
import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogDelegate.Companion.ACTION_PREVIOUSLY_CONNECTED_DEVICE
-import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogDelegate.Companion.MAX_DEVICE_ITEM_ENTRY
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
@@ -50,8 +49,10 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.produce
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -66,6 +67,7 @@ constructor(
private val bluetoothStateInteractor: BluetoothStateInteractor,
private val bluetoothAutoOnInteractor: BluetoothAutoOnInteractor,
private val audioSharingInteractor: AudioSharingInteractor,
+ private val bluetoothDeviceMetadataInteractor: BluetoothDeviceMetadataInteractor,
private val dialogTransitionAnimator: DialogTransitionAnimator,
private val activityStarter: ActivityStarter,
private val uiEventLogger: UiEventLogger,
@@ -112,15 +114,17 @@ constructor(
// deviceItemUpdate is emitted when device item list is done fetching, update UI and
// stop the progress bar.
- deviceItemInteractor.deviceItemUpdate
- .onEach {
+ combine(
+ deviceItemInteractor.deviceItemUpdate,
+ deviceItemInteractor.showSeeAllUpdate
+ ) { deviceItem, showSeeAll ->
updateDialogUiJob?.cancel()
updateDialogUiJob = launch {
dialogDelegate.apply {
onDeviceItemUpdated(
dialog,
- it.take(MAX_DEVICE_ITEM_ENTRY),
- showSeeAll = it.size > MAX_DEVICE_ITEM_ENTRY,
+ deviceItem,
+ showSeeAll,
showPairNewDevice =
bluetoothStateInteractor.isBluetoothEnabled()
)
@@ -131,8 +135,11 @@ constructor(
.launchIn(this)
// deviceItemUpdateRequest is emitted when a bluetooth callback is called, re-fetch
- // the device item list and animiate the progress bar.
- deviceItemInteractor.deviceItemUpdateRequest
+ // the device item list and animate the progress bar.
+ merge(
+ deviceItemInteractor.deviceItemUpdateRequest,
+ bluetoothDeviceMetadataInteractor.metadataUpdate
+ )
.onEach {
dialogDelegate.animateProgressBar(dialog, true)
updateDeviceItemJob?.cancel()
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
index d7893dbb0f90..e846bf7b523c 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemFactory.kt
@@ -38,7 +38,7 @@ private val actionAccessibilityLabelDisconnect =
R.string.accessibility_quick_settings_bluetooth_device_tap_to_disconnect
/** Factories to create different types of Bluetooth device items from CachedBluetoothDevice. */
-internal abstract class DeviceItemFactory {
+abstract class DeviceItemFactory {
abstract fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
@@ -136,7 +136,7 @@ internal class ActiveHearingDeviceItemFactory : ActiveMediaDeviceItemFactory() {
}
}
-internal open class AvailableMediaDeviceItemFactory : DeviceItemFactory() {
+open class AvailableMediaDeviceItemFactory : DeviceItemFactory() {
override fun isFilterMatched(
context: Context,
cachedDevice: CachedBluetoothDevice,
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
index 1526cd9675c7..95244964dc44 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
@@ -34,16 +34,18 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.isActive
import kotlinx.coroutines.withContext
/** Holds business logic for the Bluetooth Dialog after clicking on the Bluetooth QS tile. */
@SysUISingleton
-internal class DeviceItemInteractor
+class DeviceItemInteractor
@Inject
constructor(
private val bluetoothTileDialogRepository: BluetoothTileDialogRepository,
@@ -58,9 +60,13 @@ constructor(
private val mutableDeviceItemUpdate: MutableSharedFlow<List<DeviceItem>> =
MutableSharedFlow(extraBufferCapacity = 1)
- internal val deviceItemUpdate
+ val deviceItemUpdate
get() = mutableDeviceItemUpdate.asSharedFlow()
+ private val mutableShowSeeAllUpdate: MutableStateFlow<Boolean> = MutableStateFlow(false)
+ internal val showSeeAllUpdate
+ get() = mutableShowSeeAllUpdate.asStateFlow()
+
internal val deviceItemUpdateRequest: SharedFlow<Unit> =
conflatedCallbackFlow {
val listener =
@@ -139,7 +145,8 @@ constructor(
.sort(displayPriority, bluetoothAdapter?.mostRecentlyConnectedDevices)
// Only emit when the job is not cancelled
if (isActive) {
- mutableDeviceItemUpdate.tryEmit(deviceItems)
+ mutableDeviceItemUpdate.tryEmit(deviceItems.take(MAX_DEVICE_ITEM_ENTRY))
+ mutableShowSeeAllUpdate.tryEmit(deviceItems.size > MAX_DEVICE_ITEM_ENTRY)
logger.logDeviceFetch(
JobStatus.FINISHED,
trigger,
@@ -177,5 +184,6 @@ constructor(
companion object {
private const val TAG = "DeviceItemInteractor"
+ private const val MAX_DEVICE_ITEM_ENTRY = 3
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt
index d746220dd7ce..cfd4f506f169 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt
@@ -264,6 +264,9 @@ constructor(
// Keeps the lockout message up-to-date.
launch { bouncerInteractor.onLockoutStarted.collect { startLockoutCountdown() } }
+ // Start already active lockdown if it exists
+ launch { startLockoutCountdown() }
+
// Listens to relevant bouncer events
launch {
bouncerInteractor.onIncorrectBouncerInput
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt
index c780aac5aaca..63437525515c 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneTransitionInteractor.kt
@@ -41,6 +41,8 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
@@ -85,25 +87,29 @@ constructor(
*/
private val nextKeyguardStateInternal =
combine(
- keyguardInteractor.isAbleToDream,
- keyguardInteractor.isKeyguardOccluded,
- keyguardInteractor.isKeyguardGoingAway,
- ) { dreaming, occluded, keyguardGoingAway ->
- if (keyguardGoingAway) {
- KeyguardState.GONE
- } else if (occluded && !dreaming) {
- KeyguardState.OCCLUDED
- } else if (dreaming) {
- KeyguardState.DREAMING
- } else {
- KeyguardState.LOCKSCREEN
+ keyguardInteractor.isAbleToDream,
+ keyguardInteractor.isKeyguardOccluded,
+ keyguardInteractor.isKeyguardGoingAway,
+ keyguardInteractor.isKeyguardShowing,
+ ) { dreaming, occluded, keyguardGoingAway, keyguardShowing ->
+ if (keyguardGoingAway) {
+ KeyguardState.GONE
+ } else if (occluded && !dreaming) {
+ KeyguardState.OCCLUDED
+ } else if (dreaming) {
+ KeyguardState.DREAMING
+ } else if (keyguardShowing) {
+ KeyguardState.LOCKSCREEN
+ } else {
+ null
+ }
}
- }
+ .filterNotNull()
private val nextKeyguardState: StateFlow<KeyguardState> =
combine(
repository.nextLockscreenTargetState,
- nextKeyguardStateInternal,
+ nextKeyguardStateInternal.onStart { emit(KeyguardState.LOCKSCREEN) },
) { override, nextState ->
override ?: nextState
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
index 6d7cdc472f0a..b421e5932352 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
@@ -16,10 +16,7 @@
package com.android.systemui.communal.widgets
-import android.app.Activity
-import android.app.Application.ActivityLifecycleCallbacks
import android.content.Intent
-import android.content.IntentSender
import android.os.Bundle
import android.os.RemoteException
import android.util.Log
@@ -71,78 +68,12 @@ constructor(
const val EXTRA_OPEN_WIDGET_PICKER_ON_START = "open_widget_picker_on_start"
}
- /**
- * [ActivityController] handles closing the activity in the case it is backgrounded without
- * waiting for an activity result
- */
- class ActivityController(activity: Activity) {
- companion object {
- private const val STATE_EXTRA_IS_WAITING_FOR_RESULT = "extra_is_waiting_for_result"
- }
-
- private var waitingForResult: Boolean = false
-
- init {
- activity.registerActivityLifecycleCallbacks(
- object : ActivityLifecycleCallbacks {
- override fun onActivityCreated(
- activity: Activity,
- savedInstanceState: Bundle?
- ) {
- waitingForResult =
- savedInstanceState?.getBoolean(STATE_EXTRA_IS_WAITING_FOR_RESULT)
- ?: false
- }
-
- override fun onActivityStarted(activity: Activity) {
- // Nothing to implement.
- }
-
- override fun onActivityResumed(activity: Activity) {
- // Nothing to implement.
- }
-
- override fun onActivityPaused(activity: Activity) {
- // Nothing to implement.
- }
-
- override fun onActivityStopped(activity: Activity) {
- // If we're not backgrounded due to waiting for a resul (either widget
- // selection
- // or configuration), finish activity.
- if (!waitingForResult) {
- activity.finish()
- }
- }
-
- override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
- outState.putBoolean(STATE_EXTRA_IS_WAITING_FOR_RESULT, waitingForResult)
- }
-
- override fun onActivityDestroyed(activity: Activity) {
- // Nothing to implement.
- }
- }
- )
- }
-
- /**
- * Invoked when waiting for an activity result changes, either initiating such wait or
- * finishing due to the return of a result.
- */
- fun onWaitingForResult(waitingForResult: Boolean) {
- this.waitingForResult = waitingForResult
- }
- }
-
private val logger = Logger(logBuffer, "EditWidgetsActivity")
private val widgetConfigurator by lazy { widgetConfiguratorFactory.create(this) }
private var shouldOpenWidgetPickerOnStart = false
- private val activityController: ActivityController = ActivityController(this)
-
private val addWidgetActivityLauncher: ActivityResultLauncher<Intent> =
registerForActivityResult(StartActivityForResult()) { result ->
when (result.resultCode) {
@@ -267,34 +198,7 @@ constructor(
}
}
- override fun startActivityForResult(intent: Intent, requestCode: Int, options: Bundle?) {
- activityController.onWaitingForResult(true)
- super.startActivityForResult(intent, requestCode, options)
- }
-
- override fun startIntentSenderForResult(
- intent: IntentSender,
- requestCode: Int,
- fillInIntent: Intent?,
- flagsMask: Int,
- flagsValues: Int,
- extraFlags: Int,
- options: Bundle?
- ) {
- activityController.onWaitingForResult(true)
- super.startIntentSenderForResult(
- intent,
- requestCode,
- fillInIntent,
- flagsMask,
- flagsValues,
- extraFlags,
- options
- )
- }
-
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- activityController.onWaitingForResult(false)
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == WidgetConfigurationController.REQUEST_CODE) {
widgetConfigurator.setConfigurationResult(resultCode)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
index 121b4a304c3a..542b98896986 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
@@ -22,6 +22,7 @@ import android.content.Intent
import android.view.View
import android.widget.RemoteViews
import com.android.app.tracing.coroutines.launch
+import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.Flags.communalWidgetTrampolineFix
import com.android.systemui.animation.ActivityTransitionAnimator
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
@@ -29,11 +30,13 @@ import com.android.systemui.communal.domain.interactor.WidgetTrampolineInteracto
import com.android.systemui.communal.util.InteractionHandlerDelegate
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.UiBackground
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.Logger
import com.android.systemui.log.dagger.CommunalLog
import com.android.systemui.plugins.ActivityStarter
import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
@@ -41,8 +44,10 @@ import kotlinx.coroutines.Job
class WidgetInteractionHandler
@Inject
constructor(
- @Application applicationScope: CoroutineScope,
+ @Application private val applicationScope: CoroutineScope,
+ @UiBackground private val uiBackgroundContext: CoroutineContext,
private val activityStarter: ActivityStarter,
+ private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
communalSceneInteractor: CommunalSceneInteractor,
private val widgetTrampolineInteractor: WidgetTrampolineInteractor,
@CommunalLog val logBuffer: LogBuffer,
@@ -120,7 +125,14 @@ constructor(
activityStarter.startPendingIntentMaybeDismissingKeyguard(
pendingIntent,
/* dismissShade = */ false,
- /* intentSentUiThreadCallback = */ null,
+ {
+ applicationScope.launch("$TAG#awakenFromDream", uiBackgroundContext) {
+ // This activity could have started while the device is dreaming, in which case
+ // the dream would occlude the activity. In order to show the newly started
+ // activity, we wake from the dream.
+ keyguardUpdateMonitor.awakenFromDream()
+ }
+ },
controller,
fillInIntent,
extraOptions.toBundle(),
diff --git a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt
index e4b290d7d10e..15a3cbdb8072 100644
--- a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt
@@ -17,7 +17,6 @@
package com.android.systemui.display.domain.interactor
import android.companion.virtual.VirtualDeviceManager
-import android.companion.virtual.flags.Flags
import android.view.Display
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
@@ -155,8 +154,7 @@ constructor(
}
private fun isVirtualDeviceOwnedMirrorDisplay(display: Display): Boolean {
- return Flags.interactiveScreenMirror() &&
- virtualDeviceManager != null &&
+ return virtualDeviceManager != null &&
virtualDeviceManager.isVirtualDeviceOwnedMirrorDisplay(display.displayId)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt
index 9f46846f0d91..1dbe83aeb64f 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt
@@ -16,7 +16,23 @@
package com.android.systemui.inputdevice.tutorial.data.model
-data class DeviceSchedulerInfo(var isLaunched: Boolean = false, var connectTime: Long? = null) {
+import java.time.Instant
+
+data class DeviceSchedulerInfo(
+ var launchTime: Instant? = null,
+ var firstConnectionTime: Instant? = null
+) {
+ constructor(
+ launchTimeSec: Long?,
+ firstConnectionTimeSec: Long?
+ ) : this(
+ launchTimeSec?.let { Instant.ofEpochSecond(it) },
+ firstConnectionTimeSec?.let { Instant.ofEpochSecond(it) }
+ )
+
val wasEverConnected: Boolean
- get() = connectTime != null
+ get() = firstConnectionTime != null
+
+ val isLaunched: Boolean
+ get() = launchTime != null
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt
index 36b9ac70d290..d8d4bd686f07 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt
@@ -20,7 +20,6 @@ import android.content.Context
import androidx.annotation.VisibleForTesting
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
-import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
@@ -28,6 +27,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.inputdevice.tutorial.data.model.DeviceSchedulerInfo
+import java.time.Instant
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.first
@@ -43,28 +43,31 @@ class TutorialSchedulerRepository(
constructor(
@Application applicationContext: Context,
@Background backgroundScope: CoroutineScope
- ) : this(applicationContext, backgroundScope, dataStoreName = "TutorialScheduler")
+ ) : this(applicationContext, backgroundScope, dataStoreName = DATASTORE_NAME)
private val Context.dataStore: DataStore<Preferences> by
preferencesDataStore(name = dataStoreName, scope = backgroundScope)
suspend fun isLaunched(deviceType: DeviceType): Boolean = loadData()[deviceType]!!.isLaunched
+ suspend fun launchTime(deviceType: DeviceType): Instant? = loadData()[deviceType]!!.launchTime
+
suspend fun wasEverConnected(deviceType: DeviceType): Boolean =
loadData()[deviceType]!!.wasEverConnected
- suspend fun connectTime(deviceType: DeviceType): Long = loadData()[deviceType]!!.connectTime!!
+ suspend fun firstConnectionTime(deviceType: DeviceType): Instant? =
+ loadData()[deviceType]!!.firstConnectionTime
private suspend fun loadData(): Map<DeviceType, DeviceSchedulerInfo> {
return applicationContext.dataStore.data.map { pref -> getSchedulerInfo(pref) }.first()
}
- suspend fun updateConnectTime(device: DeviceType, time: Long) {
- applicationContext.dataStore.edit { pref -> pref[getConnectKey(device)] = time }
+ suspend fun updateFirstConnectionTime(device: DeviceType, time: Instant) {
+ applicationContext.dataStore.edit { pref -> pref[getConnectKey(device)] = time.epochSecond }
}
- suspend fun updateLaunch(device: DeviceType) {
- applicationContext.dataStore.edit { pref -> pref[getLaunchedKey(device)] = true }
+ suspend fun updateLaunchTime(device: DeviceType, time: Instant) {
+ applicationContext.dataStore.edit { pref -> pref[getLaunchKey(device)] = time.epochSecond }
}
private fun getSchedulerInfo(pref: Preferences): Map<DeviceType, DeviceSchedulerInfo> {
@@ -75,13 +78,13 @@ class TutorialSchedulerRepository(
}
private fun getDeviceSchedulerInfo(pref: Preferences, device: DeviceType): DeviceSchedulerInfo {
- val isLaunched = pref[getLaunchedKey(device)] ?: false
- val connectionTime = pref[getConnectKey(device)] ?: null
- return DeviceSchedulerInfo(isLaunched, connectionTime)
+ val launchTime = pref[getLaunchKey(device)]
+ val connectionTime = pref[getConnectKey(device)]
+ return DeviceSchedulerInfo(launchTime, connectionTime)
}
- private fun getLaunchedKey(device: DeviceType) =
- booleanPreferencesKey(device.name + IS_LAUNCHED_SUFFIX)
+ private fun getLaunchKey(device: DeviceType) =
+ longPreferencesKey(device.name + LAUNCH_TIME_SUFFIX)
private fun getConnectKey(device: DeviceType) =
longPreferencesKey(device.name + CONNECT_TIME_SUFFIX)
@@ -92,8 +95,9 @@ class TutorialSchedulerRepository(
}
companion object {
- const val IS_LAUNCHED_SUFFIX = "_IS_LAUNCHED"
- const val CONNECT_TIME_SUFFIX = "_CONNECTED_TIME"
+ const val DATASTORE_NAME = "TutorialScheduler"
+ const val LAUNCH_TIME_SUFFIX = "_LAUNCH_TIME"
+ const val CONNECT_TIME_SUFFIX = "_CONNECT_TIME"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
index b3b8f21a4a4b..a8d7dad42a93 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt
@@ -26,9 +26,11 @@ import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType.TOUC
import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository
import com.android.systemui.keyboard.data.repository.KeyboardRepository
import com.android.systemui.touchpad.data.repository.TouchpadRepository
+import java.time.Duration
import java.time.Instant
import javax.inject.Inject
import kotlin.time.Duration.Companion.hours
+import kotlin.time.toKotlinDuration
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.filter
@@ -84,9 +86,9 @@ constructor(
private suspend fun schedule(deviceType: DeviceType) {
if (!repo.wasEverConnected(deviceType)) {
waitForDeviceConnection(deviceType)
- repo.updateConnectTime(deviceType, Instant.now().toEpochMilli())
+ repo.updateFirstConnectionTime(deviceType, Instant.now())
}
- delay(remainingTimeMillis(start = repo.connectTime(deviceType)))
+ delay(remainingTime(start = repo.firstConnectionTime(deviceType)!!))
waitForDeviceConnection(deviceType)
}
@@ -95,9 +97,9 @@ constructor(
private suspend fun launchTutorial(tutorialType: TutorialType) {
if (tutorialType == TutorialType.KEYBOARD || tutorialType == TutorialType.BOTH)
- repo.updateLaunch(KEYBOARD)
+ repo.updateLaunchTime(KEYBOARD, Instant.now())
if (tutorialType == TutorialType.TOUCHPAD || tutorialType == TutorialType.BOTH)
- repo.updateLaunch(TOUCHPAD)
+ repo.updateLaunchTime(TOUCHPAD, Instant.now())
// TODO: launch tutorial
Log.d(TAG, "Launch tutorial for $tutorialType")
}
@@ -113,19 +115,21 @@ constructor(
return if (deviceType == KEYBOARD) TutorialType.KEYBOARD else TutorialType.TOUCHPAD
}
- private fun remainingTimeMillis(start: Long): Long {
- val elapsed = Instant.now().toEpochMilli() - start
- return LAUNCH_DELAY - elapsed
+ private fun remainingTime(start: Instant): kotlin.time.Duration {
+ val elapsed = Duration.between(start, Instant.now())
+ return LAUNCH_DELAY.minus(elapsed).toKotlinDuration()
}
companion object {
const val TAG = "TutorialSchedulerInteractor"
- private val DEFAULT_LAUNCH_DELAY = 72.hours.inWholeMilliseconds
- private val LAUNCH_DELAY: Long
+ private val DEFAULT_LAUNCH_DELAY_SEC = 72.hours.inWholeSeconds
+ private val LAUNCH_DELAY: Duration
get() =
- SystemProperties.getLong(
- "persist.peripheral_tutorial_delay_ms",
- DEFAULT_LAUNCH_DELAY
+ Duration.ofSeconds(
+ SystemProperties.getLong(
+ "persist.peripheral_tutorial_delay_sec",
+ DEFAULT_LAUNCH_DELAY_SEC
+ )
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/NewPickerUiKeyguardPreview.kt b/packages/SystemUI/src/com/android/systemui/keyguard/NewPickerUiKeyguardPreview.kt
new file mode 100644
index 000000000000..7e09a108ea40
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/NewPickerUiKeyguardPreview.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyguard
+
+import com.android.systemui.Flags
+
+/** Helper for reading or using the new picker UI flag. */
+@Suppress("NOTHING_TO_INLINE")
+object NewPickerUiKeyguardPreview {
+
+ /** Is the new picker UI enabled */
+ @JvmStatic
+ inline val isEnabled
+ get() = Flags.newPickerUi()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
index 698328ecd7fb..d49550ef4c83 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
@@ -22,7 +22,6 @@ import android.content.Intent
import android.os.UserHandle
import android.util.LayoutDirection
import com.android.systemui.Dumpable
-import com.android.systemui.res.R
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
import com.android.systemui.common.coroutine.ConflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
@@ -35,6 +34,7 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceSelectionManager
import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordancePickerRepresentation
import com.android.systemui.keyguard.shared.model.KeyguardSlotPickerRepresentation
+import com.android.systemui.res.R
import com.android.systemui.settings.UserTracker
import java.io.PrintWriter
import javax.inject.Inject
@@ -61,10 +61,13 @@ constructor(
private val remoteUserSelectionManager: KeyguardQuickAffordanceRemoteUserSelectionManager,
private val userTracker: UserTracker,
legacySettingSyncer: KeyguardQuickAffordanceLegacySettingSyncer,
- private val configs: Set<@JvmSuppressWildcards KeyguardQuickAffordanceConfig>,
+ configs: Set<@JvmSuppressWildcards KeyguardQuickAffordanceConfig>,
dumpManager: DumpManager,
userHandle: UserHandle,
) {
+ // Configs for all keyguard quick affordances, mapped by the quick affordance ID as key
+ private val configsByAffordanceId: Map<String, KeyguardQuickAffordanceConfig> =
+ configs.associateBy { it.key }
private val userId: Flow<Int> =
ConflatedCallbackFlow.conflatedCallbackFlow {
val callback =
@@ -126,7 +129,7 @@ constructor(
*/
fun getCurrentSelections(slotId: String): List<KeyguardQuickAffordanceConfig> {
val selections = selectionManager.value.getSelections().getOrDefault(slotId, emptyList())
- return configs.filter { selections.contains(it.key) }
+ return configsByAffordanceId.values.filter { selections.contains(it.key) }
}
/**
@@ -159,7 +162,7 @@ constructor(
*/
suspend fun getAffordancePickerRepresentations():
List<KeyguardQuickAffordancePickerRepresentation> {
- return configs
+ return configsByAffordanceId.values
.associateWith { config -> config.getPickerScreenState() }
.filterNot { (_, pickerState) ->
pickerState is KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
@@ -226,6 +229,11 @@ constructor(
}
}
+ /** Get the config of a quick affordance. */
+ fun getConfig(quickAffordanceId: String): KeyguardQuickAffordanceConfig? {
+ return configsByAffordanceId[quickAffordanceId]
+ }
+
private inner class Dumpster : Dumpable {
override fun dump(pw: PrintWriter, args: Array<out String>) {
val slotPickerRepresentations = getSlotPickerRepresentations()
@@ -246,7 +254,7 @@ constructor(
pw.println(" $slotId$selectionText (capacity = $capacity)")
}
pw.println("Available affordances on device:")
- configs.forEach { config ->
+ configsByAffordanceId.values.forEach { config ->
pw.println(" ${config.key} (\"${config.pickerName()}\")")
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
index 13d54bac8339..6e04133dcb4a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
@@ -128,7 +128,7 @@ constructor(
(KeyguardWmStateRefactor.isEnabled && canWakeDirectlyToGone)
if (shouldTransitionToGone) {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
+ // TODO(b/360368320): Adapt for scene framework
if (SceneContainerFlag.isEnabled) return@collect
startTransitionTo(
toState = KeyguardState.GONE,
@@ -186,7 +186,6 @@ constructor(
* PRIMARY_BOUNCER.
*/
private fun listenForAodToPrimaryBouncer() {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
scope.launch("$TAG#listenForAodToPrimaryBouncer") {
keyguardInteractor.primaryBouncerShowing
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index 90aaf0d617f7..49e4c707af18 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -107,7 +107,7 @@ constructor(
) ->
if (isWakeAndUnlock(biometricUnlockState.mode)) {
if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
+ // TODO(b/360368320): Adapt for scene framework
} else {
startTransitionTo(
KeyguardState.GONE,
@@ -138,29 +138,21 @@ constructor(
val primaryBouncerShowing = keyguardInteractor.primaryBouncerShowing.value
if (!deviceEntryInteractor.isLockscreenEnabled()) {
- if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
- } else {
+ if (!SceneContainerFlag.isEnabled) {
startTransitionTo(KeyguardState.GONE)
}
} else if (canDismissLockscreen()) {
- if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
- } else {
+ if (!SceneContainerFlag.isEnabled) {
startTransitionTo(KeyguardState.GONE)
}
} else if (primaryBouncerShowing) {
- if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
- } else {
+ if (!SceneContainerFlag.isEnabled) {
startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
}
} else if (isKeyguardOccludedLegacy) {
startTransitionTo(KeyguardState.OCCLUDED)
} else if (isIdleOnCommunal && !communalSceneKtfRefactor()) {
- if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
- } else {
+ if (!SceneContainerFlag.isEnabled) {
startTransitionTo(KeyguardState.GLANCEABLE_HUB)
}
} else if (
@@ -171,9 +163,7 @@ constructor(
) {
// This case handles tapping the power button to transition through
// dream -> off -> hub.
- if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
- } else {
+ if (!SceneContainerFlag.isEnabled) {
transitionToGlanceableHub()
}
} else {
@@ -216,30 +206,21 @@ constructor(
!isWakeAndUnlock(biometricUnlockState.mode)
) {
if (canWakeDirectlyToGone) {
- if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Check if adaptation for scene framework is
- // needed
- } else {
+ if (!SceneContainerFlag.isEnabled) {
startTransitionTo(
KeyguardState.GONE,
ownerReason = "waking from dozing"
)
}
} else if (primaryBouncerShowing) {
- if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Check if adaptation for scene framework is
- // needed
- } else {
+ if (!SceneContainerFlag.isEnabled) {
startTransitionTo(
KeyguardState.PRIMARY_BOUNCER,
ownerReason = "waking from dozing"
)
}
} else if (isIdleOnCommunal && !communalSceneKtfRefactor()) {
- if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Check if adaptation for scene framework is
- // needed
- } else {
+ if (!SceneContainerFlag.isEnabled) {
startTransitionTo(
KeyguardState.GLANCEABLE_HUB,
ownerReason = "waking from dozing"
@@ -253,10 +234,7 @@ constructor(
) {
// This case handles tapping the power button to transition through
// dream -> off -> hub.
- if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Check if adaptation for scene framework is
- // needed
- } else {
+ if (!SceneContainerFlag.isEnabled) {
transitionToGlanceableHub()
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
index c9db26dca9e2..0aa50e04087e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
@@ -231,7 +231,6 @@ constructor(
}
private fun listenForHubToGone() {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
if (communalSceneKtfRefactor()) {
scope.launch {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 5dc020f41ad3..cd3df07eea55 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -276,7 +276,6 @@ constructor(
}
private fun listenForLockscreenToGone() {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
if (KeyguardWmStateRefactor.isEnabled) return
scope.launch("$TAG#listenForLockscreenToGone") {
@@ -292,7 +291,6 @@ constructor(
}
private fun listenForLockscreenToGoneDragging() {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
if (KeyguardWmStateRefactor.isEnabled) {
// When the refactor is enabled, we no longer use isKeyguardGoingAway.
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
index 7b6949fdaa2c..0343786bb1fb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
@@ -76,7 +76,6 @@ constructor(
}
private fun listenForOccludedToPrimaryBouncer() {
- // TODO(b/336576536): Check if adaptation for scene framework is needed
if (SceneContainerFlag.isEnabled) return
scope.launch {
keyguardInteractor.primaryBouncerShowing
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index 0682d8777107..2af95f20c7d7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -53,6 +53,7 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEYGUARD_QUICK_AFFORDANCE_ID_NONE
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.policy.KeyguardStateController
import dagger.Lazy
@@ -142,14 +143,18 @@ constructor(
*
* This is useful for experiences like the lock screen preview mode, where the affordances must
* always be visible.
+ *
+ * @param overrideQuickAffordanceId If null, return the currently-set quick affordance;
+ * otherwise, override and return the correspondent [KeyguardQuickAffordanceModel].
*/
suspend fun quickAffordanceAlwaysVisible(
position: KeyguardQuickAffordancePosition,
+ overrideQuickAffordanceId: String? = null,
): Flow<KeyguardQuickAffordanceModel> {
return if (isFeatureDisabledByDevicePolicy()) {
flowOf(KeyguardQuickAffordanceModel.Hidden)
} else {
- quickAffordanceInternal(position)
+ quickAffordanceInternal(position, overrideQuickAffordanceId)
}
}
@@ -299,12 +304,24 @@ constructor(
}
private fun quickAffordanceInternal(
- position: KeyguardQuickAffordancePosition
+ position: KeyguardQuickAffordancePosition,
+ overrideAffordanceId: String? = null,
): Flow<KeyguardQuickAffordanceModel> =
repository
.get()
.selections
- .map { it[position.toSlotId()] ?: emptyList() }
+ .map { selections ->
+ val overrideQuickAffordanceConfigs =
+ overrideAffordanceId?.let {
+ if (it == KEYGUARD_QUICK_AFFORDANCE_ID_NONE) {
+ emptyList()
+ } else {
+ val config = repository.get().getConfig(it)
+ listOfNotNull(config)
+ }
+ }
+ overrideQuickAffordanceConfigs ?: selections[position.toSlotId()] ?: emptyList()
+ }
.flatMapLatest { configs -> combinedConfigs(position, configs) }
private fun combinedConfigs(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt
index 2ebd9e8c5f2b..b2183007c48c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt
@@ -71,7 +71,7 @@ constructor(
)
} else {
if (SceneContainerFlag.isEnabled) {
- // TODO(b/336576536): Some part of the transition implemented for flag off is
+ // TODO(b/360372242): Some part of the transition implemented for flag off is
// missing here. There are two things achieved with this:
// 1. Keyguard is hidden when the setup wizard is shown. This part is already
// implemented in scene container by disabling visibility instead of going
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt
index 2581b595d812..1bbe84383e48 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/quickaffordance/KeyguardQuickAffordancePosition.kt
@@ -16,7 +16,8 @@
package com.android.systemui.keyguard.shared.quickaffordance
-import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END
+import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START
/** Enumerates all possible positions for quick affordances that can appear on the lock-screen. */
enum class KeyguardQuickAffordancePosition {
@@ -25,8 +26,19 @@ enum class KeyguardQuickAffordancePosition {
fun toSlotId(): String {
return when (this) {
- BOTTOM_START -> KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START
- BOTTOM_END -> KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END
+ BOTTOM_START -> SLOT_ID_BOTTOM_START
+ BOTTOM_END -> SLOT_ID_BOTTOM_END
}
}
+
+ companion object {
+
+ /** If the slot ID does not match any string, return null. */
+ fun parseKeyguardQuickAffordancePosition(slotId: String): KeyguardQuickAffordancePosition? =
+ when (slotId) {
+ SLOT_ID_BOTTOM_START -> BOTTOM_START
+ SLOT_ID_BOTTOM_END -> BOTTOM_END
+ else -> null
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 6031ef60e1be..51ce3556ffbd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -275,6 +275,15 @@ constructor(
}
}
+ fun onStartCustomizingQuickAffordances(
+ initiallySelectedSlotId: String?,
+ ) {
+ quickAffordancesCombinedViewModel.enablePreviewMode(
+ initiallySelectedSlotId = initiallySelectedSlotId,
+ shouldHighlightSelectedAffordance = true,
+ )
+ }
+
fun onSlotSelected(slotId: String) {
if (KeyguardBottomAreaRefactor.isEnabled) {
quickAffordancesCombinedViewModel.onPreviewSlotSelected(slotId = slotId)
@@ -283,6 +292,21 @@ constructor(
}
}
+ fun onPreviewQuickAffordanceSelected(slotId: String, quickAffordanceId: String) {
+ quickAffordancesCombinedViewModel.onPreviewQuickAffordanceSelected(
+ slotId,
+ quickAffordanceId,
+ )
+ }
+
+ fun onDefaultPreview() {
+ quickAffordancesCombinedViewModel.onClearPreviewQuickAffordances()
+ quickAffordancesCombinedViewModel.enablePreviewMode(
+ initiallySelectedSlotId = null,
+ shouldHighlightSelectedAffordance = false,
+ )
+ }
+
fun destroy() {
isDestroyed = true
lockscreenSmartspaceController.disconnect()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
index 0532ee285d1d..a6108c45a479 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
@@ -31,7 +31,16 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants
+import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_HIDE_SMART_SPACE
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_QUICK_AFFORDANCE_ID
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.KEY_SLOT_ID
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_DEFAULT_PREVIEW
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_HIDE_SMART_SPACE
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_PREVIEW_QUICK_AFFORDANCE_SELECTED
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_SLOT_SELECTED
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardPreviewConstants.MESSAGE_ID_START_CUSTOMIZING_QUICK_AFFORDANCES
import com.android.systemui.util.kotlin.logD
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -59,7 +68,7 @@ constructor(
return try {
val renderer =
if (Flags.lockscreenPreviewRendererCreateOnMainThread()) {
- runBlocking ("$TAG#previewRendererFactory.create", mainDispatcher) {
+ runBlocking("$TAG#previewRendererFactory.create", mainDispatcher) {
previewRendererFactory.create(request)
}
} else {
@@ -157,16 +166,35 @@ class PreviewLifecycleObserver(
}
when (message.what) {
- KeyguardPreviewConstants.MESSAGE_ID_SLOT_SELECTED -> {
- message.data.getString(KeyguardPreviewConstants.KEY_SLOT_ID)?.let { slotId ->
+ MESSAGE_ID_START_CUSTOMIZING_QUICK_AFFORDANCES -> {
+ checkNotNull(renderer)
+ .onStartCustomizingQuickAffordances(
+ initiallySelectedSlotId =
+ message.data.getString(KEY_INITIALLY_SELECTED_SLOT_ID)
+ ?: SLOT_ID_BOTTOM_START
+ )
+ }
+ MESSAGE_ID_SLOT_SELECTED -> {
+ message.data.getString(KEY_SLOT_ID)?.let { slotId ->
checkNotNull(renderer).onSlotSelected(slotId = slotId)
}
}
- KeyguardPreviewConstants.MESSAGE_ID_HIDE_SMART_SPACE -> {
- checkNotNull(renderer)
- .hideSmartspace(
- message.data.getBoolean(KeyguardPreviewConstants.KEY_HIDE_SMART_SPACE)
- )
+ MESSAGE_ID_PREVIEW_QUICK_AFFORDANCE_SELECTED -> {
+ val slotId = message.data.getString(KEY_SLOT_ID)
+ val quickAffordanceId = message.data.getString(KEY_QUICK_AFFORDANCE_ID)
+ if (slotId != null && quickAffordanceId != null) {
+ checkNotNull(renderer)
+ .onPreviewQuickAffordanceSelected(
+ slotId = slotId,
+ quickAffordanceId = quickAffordanceId,
+ )
+ }
+ }
+ MESSAGE_ID_DEFAULT_PREVIEW -> {
+ checkNotNull(renderer).onDefaultPreview()
+ }
+ MESSAGE_ID_HIDE_SMART_SPACE -> {
+ checkNotNull(renderer).hideSmartspace(message.data.getBoolean(KEY_HIDE_SMART_SPACE))
}
else -> checkNotNull(onDestroy).invoke(this)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
index 2426f9745885..c885c9a5a29b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
@@ -20,6 +20,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import androidx.annotation.VisibleForTesting
import com.android.app.tracing.FlowTracing.traceEmissionCount
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.NewPickerUiKeyguardPreview
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -29,6 +30,7 @@ import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -164,13 +166,36 @@ constructor(
.map { alpha -> alpha >= AFFORDANCE_FULLY_OPAQUE_ALPHA_THRESHOLD }
.distinctUntilChanged()
+ private val previewAffordances =
+ MutableStateFlow<Map<KeyguardQuickAffordancePosition, String>>(emptyMap())
+
/** An observable for the view-model of the "start button" quick affordance. */
val startButton: Flow<KeyguardQuickAffordanceViewModel> =
- button(KeyguardQuickAffordancePosition.BOTTOM_START)
+ if (NewPickerUiKeyguardPreview.isEnabled) {
+ previewAffordances.flatMapLatestConflated {
+ button(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ overrideQuickAffordanceId = it[KeyguardQuickAffordancePosition.BOTTOM_START],
+ )
+ }
+ } else {
+ button(
+ KeyguardQuickAffordancePosition.BOTTOM_START,
+ )
+ }
/** An observable for the view-model of the "end button" quick affordance. */
val endButton: Flow<KeyguardQuickAffordanceViewModel> =
- button(KeyguardQuickAffordancePosition.BOTTOM_END)
+ if (NewPickerUiKeyguardPreview.isEnabled) {
+ previewAffordances.flatMapLatestConflated {
+ button(
+ position = KeyguardQuickAffordancePosition.BOTTOM_END,
+ overrideQuickAffordanceId = it[KeyguardQuickAffordancePosition.BOTTOM_END],
+ )
+ }
+ } else {
+ button(KeyguardQuickAffordancePosition.BOTTOM_END)
+ }
/**
* Notifies that a slot with the given ID has been selected in the preview experience that is
@@ -183,6 +208,28 @@ constructor(
}
/**
+ * Notifies to preview an affordance at a given slot ID. This is ignored for the real lock
+ * screen experience.
+ */
+ fun onPreviewQuickAffordanceSelected(slotId: String, affordanceId: String) {
+ val position =
+ KeyguardQuickAffordancePosition.parseKeyguardQuickAffordancePosition(slotId) ?: return
+ previewAffordances.value =
+ previewAffordances.value.toMutableMap().let {
+ it[position] = affordanceId
+ HashMap(it)
+ }
+ }
+
+ /**
+ * Notifies to clear up the preview affordances map. This is ignored for the real lock screen
+ * experience.
+ */
+ fun onClearPreviewQuickAffordances() {
+ previewAffordances.value = emptyMap()
+ }
+
+ /**
* Puts this view-model in "preview mode", which means it's being used for UI that is rendering
* the lock screen preview in wallpaper picker / settings and not the real experience on the
* lock screen.
@@ -207,14 +254,16 @@ constructor(
}
private fun button(
- position: KeyguardQuickAffordancePosition
+ position: KeyguardQuickAffordancePosition,
+ overrideQuickAffordanceId: String? = null,
): Flow<KeyguardQuickAffordanceViewModel> {
return previewMode
.flatMapLatest { previewMode ->
combine(
if (previewMode.isInPreviewMode) {
quickAffordanceInteractor.quickAffordanceAlwaysVisible(
- position = position
+ position = position,
+ overrideQuickAffordanceId = overrideQuickAffordanceId,
)
} else {
quickAffordanceInteractor.quickAffordance(position = position)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
index c4f539a4acdf..408fc6d06461 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
@@ -13,4 +13,12 @@ per-file *Doze* = file:../keyguard/OWNERS
per-file *Keyboard* = set noparent
per-file *Keyboard* = file:../keyguard/OWNERS
per-file *Keyguard* = set noparent
-per-file *Keyguard* = file:../keyguard/OWNERS \ No newline at end of file
+per-file *Keyguard* = file:../keyguard/OWNERS
+per-file *Notification* = set noparent
+per-file *Notification* = file:notification/OWNERS
+per-file *Mode* = set noparent
+per-file *Mode* = file:notification/OWNERS
+per-file *RemoteInput* = set noparent
+per-file *RemoteInput* = file:notification/OWNERS
+per-file *EmptyShadeView* = set noparent
+per-file *EmptyShadeView* = file:notification/OWNERS \ No newline at end of file
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 20b1fffc2c02..e8020764bce4 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
@@ -258,7 +258,7 @@ public class NotificationStackScrollLayout
private float mOverScrolledBottomPixels;
private final ListenerSet<Runnable> mStackHeightChangedListeners = new ListenerSet<>();
private final ListenerSet<Runnable> mHeadsUpHeightChangedListeners = new ListenerSet<>();
- private NotificationLogger.OnChildLocationsChangedListener mListener;
+ private NotificationLogger.OnChildLocationsChangedListener mLegacyLocationsChangedListener;
private OnNotificationLocationsChangedListener mLocationsChangedListener;
private OnOverscrollTopChangedListener mOverscrollTopChangedListener;
private ExpandableView.OnHeightChangedListener mOnHeightChangedListener;
@@ -1281,7 +1281,7 @@ public class NotificationStackScrollLayout
public void setChildLocationsChangedListener(
NotificationLogger.OnChildLocationsChangedListener listener) {
NotificationsLiveDataStoreRefactor.assertInLegacyMode();
- mListener = listener;
+ mLegacyLocationsChangedListener = listener;
}
private void setMaxLayoutHeight(int maxLayoutHeight) {
@@ -4433,8 +4433,8 @@ public class NotificationStackScrollLayout
mLocationsChangedListener.onChildLocationsChanged(collectVisibleLocationsCallable);
}
} else {
- if (mListener != null) {
- mListener.onChildLocationsChanged();
+ if (mLegacyLocationsChangedListener != null) {
+ mLegacyLocationsChangedListener.onChildLocationsChanged();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
index 1a4708170a05..460423378dff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
@@ -333,10 +333,6 @@ constructor(
}
if (intent.isActivity) {
assistManagerLazy.get().hideAssist()
- // This activity could have started while the device is dreaming, in which case
- // the dream would occlude the activity. In order to show the newly started
- // activity, we wake from the dream.
- keyguardUpdateMonitor.awakenFromDream()
}
intentSentUiThreadCallback?.let { postOnUiThread(runnable = it) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt
index fa400593c990..0451ce6d9fce 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractor.kt
@@ -19,6 +19,7 @@ package com.android.systemui.volume.panel.component.volume.domain.interactor
import android.media.AudioDeviceInfo
import android.media.AudioManager
import com.android.settingslib.volume.data.repository.AudioRepository
+import com.android.settingslib.volume.domain.interactor.AudioModeInteractor
import com.android.settingslib.volume.shared.model.AudioStream
import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor
import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession
@@ -42,6 +43,7 @@ constructor(
@VolumePanelScope scope: CoroutineScope,
mediaOutputInteractor: MediaOutputInteractor,
audioRepository: AudioRepository,
+ audioModeInteractor: AudioModeInteractor,
) {
val volumePanelSliders: StateFlow<List<SliderType>> =
@@ -49,9 +51,14 @@ constructor(
mediaOutputInteractor.activeMediaDeviceSessions,
mediaOutputInteractor.defaultActiveMediaSession.filterData(),
audioRepository.communicationDevice,
- ) { activeSessions, defaultSession, communicationDevice ->
+ audioModeInteractor.isOngoingCall,
+ ) { activeSessions, defaultSession, communicationDevice, isOngoingCall ->
coroutineScope {
val viewModels = buildList {
+ if (isOngoingCall) {
+ addCall(communicationDevice?.type)
+ }
+
if (defaultSession?.isTheSameSession(activeSessions.remote) == true) {
addSession(activeSessions.remote)
addStream(AudioManager.STREAM_MUSIC)
@@ -60,11 +67,10 @@ constructor(
addSession(activeSessions.remote)
}
- if (communicationDevice?.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
- addStream(AudioManager.STREAM_BLUETOOTH_SCO)
- } else {
- addStream(AudioManager.STREAM_VOICE_CALL)
+ if (!isOngoingCall) {
+ addCall(communicationDevice?.type)
}
+
addStream(AudioManager.STREAM_RING)
addStream(AudioManager.STREAM_NOTIFICATION)
addStream(AudioManager.STREAM_ALARM)
@@ -74,6 +80,14 @@ constructor(
}
.stateIn(scope, SharingStarted.Eagerly, emptyList())
+ private fun MutableList<SliderType>.addCall(communicationDeviceType: Int?) {
+ if (communicationDeviceType == AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
+ addStream(AudioManager.STREAM_BLUETOOTH_SCO)
+ } else {
+ addStream(AudioManager.STREAM_VOICE_CALL)
+ }
+ }
+
private fun MutableList<SliderType>.addSession(remoteMediaDeviceSession: MediaDeviceSession?) {
if (remoteMediaDeviceSession?.canAdjustVolume == true) {
add(SliderType.MediaDeviceCast(remoteMediaDeviceSession))
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt
index 4b4d69a31db4..45732deb9aa6 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt
@@ -16,6 +16,7 @@
package com.android.systemui.volume.panel.component.volume.ui.viewmodel
+import com.android.settingslib.volume.domain.interactor.AudioModeInteractor
import com.android.settingslib.volume.shared.model.AudioStream
import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaDeviceSessionInteractor
import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor
@@ -35,9 +36,11 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
@@ -58,24 +61,31 @@ constructor(
mediaDeviceSessionInteractor: MediaDeviceSessionInteractor,
private val streamSliderViewModelFactory: AudioStreamSliderViewModel.Factory,
private val castVolumeSliderViewModelFactory: CastVolumeSliderViewModel.Factory,
+ audioModeInteractor: AudioModeInteractor,
streamsInteractor: AudioSlidersInteractor,
) {
private val mutableIsExpanded = MutableStateFlow<Boolean?>(null)
- private val isPlaybackActive: Flow<Boolean?> =
- mediaOutputInteractor.defaultActiveMediaSession
- .filterData()
- .flatMapLatest { session ->
- if (session == null) {
- flowOf(false)
- } else {
- mediaDeviceSessionInteractor.playbackState(session).map { it?.isActive == true }
- }
+ private val isActive: Flow<Boolean?> =
+ combine(
+ audioModeInteractor.isOngoingCall,
+ mediaOutputInteractor.defaultActiveMediaSession.filterData().flatMapLatest { session
+ ->
+ if (session == null) {
+ flowOf(false)
+ } else {
+ mediaDeviceSessionInteractor.playbackState(session).map {
+ it?.isActive == true
+ }
+ }
+ },
+ ) { isOngoingCall, isPlaybackActive ->
+ isOngoingCall || isPlaybackActive
}
- .onEach { isPlaybackActive -> mutableIsExpanded.value = !isPlaybackActive }
.stateIn(scope, SharingStarted.Eagerly, null)
+
private val portraitExpandable: Flow<SlidersExpandableViewModel> =
- isPlaybackActive
+ isActive
.filterNotNull()
.flatMapLatest { isActive ->
if (isActive) {
@@ -105,6 +115,10 @@ constructor(
}
.stateIn(scope, SharingStarted.Eagerly, emptyList())
+ init {
+ isActive.filterNotNull().onEach { mutableIsExpanded.value = !it }.launchIn(scope)
+ }
+
fun isExpandable(isPortrait: Boolean): Flow<SlidersExpandableViewModel> {
return if (isPortrait) {
portraitExpandable
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
index 5ff3915c76f9..113a8c05ee66 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java
@@ -45,6 +45,7 @@ import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.util.settings.SecureSettings;
@@ -90,6 +91,8 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase {
private SecureSettings mSecureSettings;
@Mock
private Lazy<ViewCapture> mLazyViewCapture;
+ @Mock
+ private NavigationModeController mNavigationModeController;
@Before
public void setUp() throws Exception {
@@ -163,7 +166,8 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase {
enableAccessibilityFloatingMenuConfig();
mController = setUpController();
mController.mFloatingMenu = new MenuViewLayerController(mContextWrapper, mWindowManager,
- mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings);
+ mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings,
+ mNavigationModeController);
captureKeyguardUpdateMonitorCallback();
mKeyguardCallback.onUserUnlocked();
@@ -190,7 +194,8 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase {
enableAccessibilityFloatingMenuConfig();
mController = setUpController();
mController.mFloatingMenu = new MenuViewLayerController(mContextWrapper, mWindowManager,
- mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings);
+ mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings,
+ mNavigationModeController);
captureKeyguardUpdateMonitorCallback();
mKeyguardCallback.onUserSwitching(fakeUserId);
@@ -204,7 +209,8 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase {
enableAccessibilityFloatingMenuConfig();
mController = setUpController();
mController.mFloatingMenu = new MenuViewLayerController(mContextWrapper, mWindowManager,
- mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings);
+ mViewCaptureAwareWindowManager, mAccessibilityManager, mSecureSettings,
+ mNavigationModeController);
captureKeyguardUpdateMonitorCallback();
mKeyguardCallback.onUserUnlocked();
mKeyguardCallback.onKeyguardVisibilityChanged(true);
@@ -340,7 +346,7 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase {
new AccessibilityFloatingMenuController(mContextWrapper, windowManager,
viewCaptureAwareWindowManager, displayManager, mAccessibilityManager,
mTargetsObserver, mModeObserver, mKeyguardUpdateMonitor, mSecureSettings,
- displayTracker);
+ displayTracker, mNavigationModeController);
controller.init();
return controller;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
index c5509ac44046..157cccc3d62f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegateTest.java
@@ -44,6 +44,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.accessibility.utils.TestUtils;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.res.R;
import com.android.systemui.util.settings.SecureSettings;
@@ -94,7 +95,8 @@ public class MenuItemAccessibilityDelegateTest extends SysuiTestCase {
mMenuViewLayer = spy(new MenuViewLayer(
mContext, stubWindowManager, mAccessibilityManager,
stubMenuViewModel, stubMenuViewAppearance, mMenuView,
- mock(IAccessibilityFloatingMenu.class), mSecureSettings));
+ mock(IAccessibilityFloatingMenu.class), mSecureSettings,
+ mock(NavigationModeController.class)));
doNothing().when(mMenuViewLayer).gotoEditScreen();
doReturn(mDraggableBounds).when(mMenuView).getMenuDraggableBounds();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java
index 07ce7b9352c1..fcdeff9ab683 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerControllerTest.java
@@ -21,6 +21,7 @@ import static android.view.WindowInsets.Type.systemBars;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -41,6 +42,7 @@ import androidx.test.filters.SmallTest;
import com.android.app.viewcapture.ViewCapture;
import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.util.settings.SecureSettings;
import kotlin.Lazy;
@@ -90,7 +92,8 @@ public class MenuViewLayerControllerTest extends SysuiTestCase {
when(mWindowMetrics.getBounds()).thenReturn(new Rect(0, 0, 1080, 2340));
when(mWindowMetrics.getWindowInsets()).thenReturn(stubDisplayInsets());
mMenuViewLayerController = new MenuViewLayerController(mContext, mWindowManager,
- viewCaptureAwareWm, mAccessibilityManager, mSecureSettings);
+ viewCaptureAwareWm, mAccessibilityManager, mSecureSettings,
+ mock(NavigationModeController.class));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
index e1e6139982e7..c451c32c4587 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
@@ -81,6 +81,7 @@ import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestableContext;
import com.android.systemui.accessibility.utils.TestUtils;
+import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.res.R;
import com.android.systemui.util.settings.SecureSettings;
import com.android.wm.shell.shared.magnetictarget.MagnetizedObject;
@@ -169,7 +170,7 @@ public class MenuViewLayerTest extends SysuiTestCase {
mMenuViewLayer = spy(new MenuViewLayer(mSpyContext, mStubWindowManager,
mStubAccessibilityManager, mMenuViewModel, menuViewAppearance, mMenuView,
- mFloatingMenu, mSecureSettings));
+ mFloatingMenu, mSecureSettings, mock(NavigationModeController.class)));
mMenuAnimationController = mMenuView.getMenuAnimationController();
doNothing().when(mSpyContext).startActivity(any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorKosmos.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorKosmos.kt
new file mode 100644
index 000000000000..969e26a8d884
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorKosmos.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth.qsdialog
+
+import com.android.systemui.bluetooth.bluetoothAdapter
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import org.mockito.kotlin.mock
+
+val Kosmos.deviceItemInteractor: DeviceItemInteractor by
+ Kosmos.Fixture { mock<DeviceItemInteractor>() }
+
+val Kosmos.bluetoothDeviceMetadataInteractor by
+ Kosmos.Fixture {
+ BluetoothDeviceMetadataInteractor(
+ deviceItemInteractor,
+ bluetoothAdapter,
+ bluetoothTileDialogLogger,
+ fakeExecutor,
+ testDispatcher,
+ )
+ }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt
new file mode 100644
index 000000000000..f06b105a9e26
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothDeviceMetadataInteractorTest.kt
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth.qsdialog
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.bluetooth.bluetoothAdapter
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class BluetoothDeviceMetadataInteractorTest : SysuiTestCase() {
+ @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+ private val kosmos = testKosmos().apply { testDispatcher = UnconfinedTestDispatcher() }
+
+ private val deviceItemUpdate: MutableSharedFlow<List<DeviceItem>> = MutableSharedFlow()
+ @Mock private lateinit var cachedDevice1: CachedBluetoothDevice
+ @Mock private lateinit var bluetoothDevice1: BluetoothDevice
+ @Mock private lateinit var cachedDevice2: CachedBluetoothDevice
+ @Mock private lateinit var bluetoothDevice2: BluetoothDevice
+ @Captor
+ private lateinit var argumentCaptor: ArgumentCaptor<BluetoothAdapter.OnMetadataChangedListener>
+ private lateinit var interactor: BluetoothDeviceMetadataInteractor
+
+ @Before
+ fun setUp() {
+ with(kosmos) {
+ whenever(deviceItemInteractor.deviceItemUpdate).thenReturn(deviceItemUpdate)
+
+ whenever(cachedDevice1.device).thenReturn(bluetoothDevice1)
+ whenever(cachedDevice1.name).thenReturn(DEVICE_NAME)
+ whenever(cachedDevice1.address).thenReturn(DEVICE_ADDRESS)
+ whenever(cachedDevice1.connectionSummary).thenReturn(CONNECTION_SUMMARY)
+ whenever(bluetoothDevice1.address).thenReturn(DEVICE_ADDRESS)
+
+ whenever(cachedDevice2.device).thenReturn(bluetoothDevice2)
+ whenever(cachedDevice2.name).thenReturn(DEVICE_NAME)
+ whenever(cachedDevice2.address).thenReturn(DEVICE_ADDRESS)
+ whenever(cachedDevice2.connectionSummary).thenReturn(CONNECTION_SUMMARY)
+ whenever(bluetoothDevice2.address).thenReturn(DEVICE_ADDRESS)
+
+ interactor = bluetoothDeviceMetadataInteractor
+ }
+ }
+
+ @Test
+ fun deviceItemUpdateEmpty_doNothing() {
+ with(kosmos) {
+ testScope.runTest {
+ val update by collectLastValue(interactor.metadataUpdate)
+ deviceItemUpdate.emit(emptyList())
+ runCurrent()
+
+ assertThat(update).isNull()
+ verify(bluetoothAdapter, never()).addOnMetadataChangedListener(any(), any(), any())
+ verify(bluetoothAdapter, never()).removeOnMetadataChangedListener(any(), any())
+ }
+ }
+ }
+
+ @Test
+ fun deviceItemUpdate_registerListener() {
+ with(kosmos) {
+ testScope.runTest {
+ val deviceItem = AvailableMediaDeviceItemFactory().create(context, cachedDevice1)
+ val update by collectLastValue(interactor.metadataUpdate)
+ deviceItemUpdate.emit(listOf(deviceItem))
+ runCurrent()
+
+ assertThat(update).isNull()
+ verify(bluetoothAdapter)
+ .addOnMetadataChangedListener(eq(bluetoothDevice1), any(), any())
+ verify(bluetoothAdapter, never()).removeOnMetadataChangedListener(any(), any())
+ }
+ }
+ }
+
+ @Test
+ fun deviceItemUpdate_sameDeviceItems_registerListenerOnce() {
+ with(kosmos) {
+ testScope.runTest {
+ val deviceItem = AvailableMediaDeviceItemFactory().create(context, cachedDevice1)
+ val update by collectLastValue(interactor.metadataUpdate)
+ deviceItemUpdate.emit(listOf(deviceItem))
+ deviceItemUpdate.emit(listOf(deviceItem))
+ runCurrent()
+
+ assertThat(update).isNull()
+ verify(bluetoothAdapter)
+ .addOnMetadataChangedListener(eq(bluetoothDevice1), any(), any())
+ verify(bluetoothAdapter, never()).removeOnMetadataChangedListener(any(), any())
+ }
+ }
+ }
+
+ @Test
+ fun deviceItemUpdate_differentDeviceItems_unregisterOldAndRegisterNew() {
+ with(kosmos) {
+ testScope.runTest {
+ val deviceItem1 = AvailableMediaDeviceItemFactory().create(context, cachedDevice1)
+ val deviceItem2 = AvailableMediaDeviceItemFactory().create(context, cachedDevice2)
+ val update by collectLastValue(interactor.metadataUpdate)
+ deviceItemUpdate.emit(listOf(deviceItem1))
+ deviceItemUpdate.emit(listOf(deviceItem1, deviceItem2))
+ runCurrent()
+
+ assertThat(update).isNull()
+ verify(bluetoothAdapter, times(2))
+ .addOnMetadataChangedListener(eq(bluetoothDevice1), any(), any())
+ verify(bluetoothAdapter)
+ .addOnMetadataChangedListener(eq(bluetoothDevice2), any(), any())
+ verify(bluetoothAdapter)
+ .removeOnMetadataChangedListener(eq(bluetoothDevice1), any())
+ }
+ }
+ }
+
+ @Test
+ fun metadataUpdate_triggerCallback_emit() {
+ with(kosmos) {
+ testScope.runTest {
+ val deviceItem = AvailableMediaDeviceItemFactory().create(context, cachedDevice1)
+ val update by collectLastValue(interactor.metadataUpdate)
+ deviceItemUpdate.emit(listOf(deviceItem))
+ runCurrent()
+
+ assertThat(update).isNull()
+ verify(bluetoothAdapter)
+ .addOnMetadataChangedListener(
+ eq(bluetoothDevice1),
+ any(),
+ argumentCaptor.capture()
+ )
+
+ val listener = argumentCaptor.value
+ listener.onMetadataChanged(
+ bluetoothDevice1,
+ BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY,
+ ByteArray(0)
+ )
+ assertThat(update).isEqualTo(Unit)
+ }
+ }
+ }
+
+ @Test
+ fun metadataUpdate_triggerCallbackNonBatteryKey_doNothing() {
+ with(kosmos) {
+ testScope.runTest {
+ val deviceItem = AvailableMediaDeviceItemFactory().create(context, cachedDevice1)
+ val update by collectLastValue(interactor.metadataUpdate)
+ deviceItemUpdate.emit(listOf(deviceItem))
+ runCurrent()
+
+ assertThat(update).isNull()
+ verify(bluetoothAdapter)
+ .addOnMetadataChangedListener(
+ eq(bluetoothDevice1),
+ any(),
+ argumentCaptor.capture()
+ )
+
+ val listener = argumentCaptor.value
+ listener.onMetadataChanged(
+ bluetoothDevice1,
+ BluetoothDevice.METADATA_MODEL_NAME,
+ ByteArray(0)
+ )
+
+ assertThat(update).isNull()
+ }
+ }
+ }
+
+ companion object {
+ private const val DEVICE_NAME = "DeviceName"
+ private const val CONNECTION_SUMMARY = "ConnectionSummary"
+ private const val DEVICE_ADDRESS = "04:52:C7:0B:D8:3C"
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
index 9abb85d249eb..d7bea6680c2d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
@@ -77,6 +77,8 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
@Mock private lateinit var audioSharingInteractor: AudioSharingInteractor
+ @Mock private lateinit var bluetoothDeviceMetadataInteractor: BluetoothDeviceMetadataInteractor
+
@Mock private lateinit var deviceItemInteractor: DeviceItemInteractor
@Mock private lateinit var deviceItemActionInteractor: DeviceItemActionInteractor
@@ -138,6 +140,7 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
)
),
audioSharingInteractor,
+ bluetoothDeviceMetadataInteractor,
mDialogTransitionAnimator,
activityStarter,
uiEventLogger,
@@ -150,6 +153,8 @@ class BluetoothTileDialogViewModelTest : SysuiTestCase() {
whenever(deviceItemInteractor.deviceItemUpdate).thenReturn(MutableSharedFlow())
whenever(deviceItemInteractor.deviceItemUpdateRequest)
.thenReturn(MutableStateFlow(Unit).asStateFlow())
+ whenever(deviceItemInteractor.showSeeAllUpdate).thenReturn(getMutableStateFlow(false))
+ whenever(bluetoothDeviceMetadataInteractor.metadataUpdate).thenReturn(MutableSharedFlow())
whenever(mBluetoothTileDialogDelegateDelegateFactory.create(any(), anyInt(), any(), any()))
.thenReturn(bluetoothTileDialogDelegate)
whenever(bluetoothTileDialogDelegate.createDialog()).thenReturn(sysuiDialog)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
index 7f7abaf9b689..194590c1f626 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
@@ -113,9 +113,11 @@ class DeviceItemInteractorTest : SysuiTestCase() {
)
val latest by collectLastValue(interactor.deviceItemUpdate)
+ val latestShowSeeAll by collectLastValue(interactor.showSeeAllUpdate)
interactor.updateDeviceItems(mContext, DeviceFetchTrigger.FIRST_LOAD)
assertThat(latest).isEqualTo(emptyList<DeviceItem>())
+ assertThat(latestShowSeeAll).isFalse()
}
}
@@ -128,9 +130,11 @@ class DeviceItemInteractorTest : SysuiTestCase() {
)
val latest by collectLastValue(interactor.deviceItemUpdate)
+ val latestShowSeeAll by collectLastValue(interactor.showSeeAllUpdate)
interactor.updateDeviceItems(mContext, DeviceFetchTrigger.FIRST_LOAD)
assertThat(latest).isEqualTo(emptyList<DeviceItem>())
+ assertThat(latestShowSeeAll).isFalse()
}
}
@@ -143,9 +147,11 @@ class DeviceItemInteractorTest : SysuiTestCase() {
)
val latest by collectLastValue(interactor.deviceItemUpdate)
+ val latestShowSeeAll by collectLastValue(interactor.showSeeAllUpdate)
interactor.updateDeviceItems(mContext, DeviceFetchTrigger.FIRST_LOAD)
assertThat(latest).isEqualTo(listOf(deviceItem1))
+ assertThat(latestShowSeeAll).isFalse()
}
}
@@ -158,9 +164,11 @@ class DeviceItemInteractorTest : SysuiTestCase() {
)
val latest by collectLastValue(interactor.deviceItemUpdate)
+ val latestShowSeeAll by collectLastValue(interactor.showSeeAllUpdate)
interactor.updateDeviceItems(mContext, DeviceFetchTrigger.FIRST_LOAD)
assertThat(latest).isEqualTo(listOf(deviceItem2, deviceItem2))
+ assertThat(latestShowSeeAll).isFalse()
}
}
@@ -184,9 +192,11 @@ class DeviceItemInteractorTest : SysuiTestCase() {
`when`(deviceItem2.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE)
val latest by collectLastValue(interactor.deviceItemUpdate)
+ val latestShowSeeAll by collectLastValue(interactor.showSeeAllUpdate)
interactor.updateDeviceItems(mContext, DeviceFetchTrigger.FIRST_LOAD)
assertThat(latest).isEqualTo(listOf(deviceItem2, deviceItem1))
+ assertThat(latestShowSeeAll).isFalse()
}
}
@@ -207,9 +217,30 @@ class DeviceItemInteractorTest : SysuiTestCase() {
`when`(deviceItem2.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
val latest by collectLastValue(interactor.deviceItemUpdate)
+ val latestShowSeeAll by collectLastValue(interactor.showSeeAllUpdate)
interactor.updateDeviceItems(mContext, DeviceFetchTrigger.FIRST_LOAD)
assertThat(latest).isEqualTo(listOf(deviceItem2, deviceItem1))
+ assertThat(latestShowSeeAll).isFalse()
+ }
+ }
+
+ @Test
+ fun testUpdateDeviceItems_showMaxDeviceItems_showSeeAll() {
+ testScope.runTest {
+ `when`(bluetoothTileDialogRepository.cachedDevices)
+ .thenReturn(listOf(cachedDevice2, cachedDevice2, cachedDevice2, cachedDevice2))
+ `when`(adapter.mostRecentlyConnectedDevices).thenReturn(null)
+ interactor.setDeviceItemFactoryListForTesting(
+ listOf(createFactory({ true }, deviceItem2))
+ )
+
+ val latest by collectLastValue(interactor.deviceItemUpdate)
+ val latestShowSeeAll by collectLastValue(interactor.showSeeAllUpdate)
+ interactor.updateDeviceItems(mContext, DeviceFetchTrigger.FIRST_LOAD)
+
+ assertThat(latest).isEqualTo(listOf(deviceItem2, deviceItem2, deviceItem2))
+ assertThat(latestShowSeeAll).isTrue()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt
index fd9964f938c8..a2b50fd2ec17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractorTest.kt
@@ -17,8 +17,6 @@
package com.android.systemui.display.domain.interactor
import android.companion.virtual.VirtualDeviceManager
-import android.companion.virtual.flags.Flags.FLAG_INTERACTIVE_SCREEN_MIRROR
-import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper
import android.view.Display
import android.view.Display.TYPE_EXTERNAL
@@ -160,7 +158,6 @@ class ConnectedDisplayInteractorTest : SysuiTestCase() {
}
@Test
- @EnableFlags(FLAG_INTERACTIVE_SCREEN_MIRROR)
fun displayState_virtualDeviceOwnedMirrorVirtualDisplay_connected() =
testScope.runTest {
whenever(virtualDeviceManager.isVirtualDeviceOwnedMirrorDisplay(anyInt()))
@@ -183,7 +180,6 @@ class ConnectedDisplayInteractorTest : SysuiTestCase() {
}
@Test
- @EnableFlags(FLAG_INTERACTIVE_SCREEN_MIRROR)
fun virtualDeviceOwnedMirrorVirtualDisplay_emitsConnectedDisplayAddition() =
testScope.runTest {
whenever(virtualDeviceManager.isVirtualDeviceOwnedMirrorDisplay(anyInt()))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/TutorialSchedulerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/TutorialSchedulerRepositoryTest.kt
index 7583399c784a..1d96c4d67c77 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/TutorialSchedulerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/inputdevice/data/repository/TutorialSchedulerRepositoryTest.kt
@@ -68,20 +68,23 @@ class TutorialSchedulerRepositoryTest : SysuiTestCase() {
@Test
fun connectKeyboard() =
testScope.runTest {
- val now = Instant.now().toEpochMilli()
- underTest.updateConnectTime(KEYBOARD, now)
+ val now = Instant.now()
+ underTest.updateFirstConnectionTime(KEYBOARD, now)
assertThat(underTest.wasEverConnected(KEYBOARD)).isTrue()
- assertThat(underTest.connectTime(KEYBOARD)).isEqualTo(now)
+ assertThat(underTest.firstConnectionTime(KEYBOARD)!!.epochSecond)
+ .isEqualTo(now.epochSecond)
assertThat(underTest.wasEverConnected(TOUCHPAD)).isFalse()
}
@Test
fun launchKeyboard() =
testScope.runTest {
- underTest.updateLaunch(KEYBOARD)
+ val now = Instant.now()
+ underTest.updateLaunchTime(KEYBOARD, now)
assertThat(underTest.isLaunched(KEYBOARD)).isTrue()
+ assertThat(underTest.launchTime(KEYBOARD)!!.epochSecond).isEqualTo(now.epochSecond)
assertThat(underTest.isLaunched(TOUCHPAD)).isFalse()
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
index 24bea2ce51c7..73b9f5783004 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
@@ -20,6 +20,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import android.app.admin.DevicePolicyManager
import android.content.Intent
import android.os.UserHandle
+import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
@@ -402,6 +403,67 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
}
@Test
+ @EnableFlags(com.android.systemui.Flags.FLAG_NEW_PICKER_UI)
+ fun startButton_inPreviewMode_onPreviewQuickAffordanceSelected() =
+ testScope.runTest {
+ underTest.onPreviewSlotSelected(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
+ underTest.enablePreviewMode(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, true)
+
+ repository.setKeyguardShowing(false)
+ val latest = collectLastValue(underTest.startButton)
+
+ val icon: Icon = mock()
+ val testConfig =
+ TestConfig(
+ isVisible = true,
+ isClickable = true,
+ isActivated = true,
+ icon = icon,
+ canShowWhileLocked = false,
+ intent = null,
+ slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(),
+ )
+ val defaultConfigKey =
+ setUpQuickAffordanceModel(
+ position = KeyguardQuickAffordancePosition.BOTTOM_START,
+ testConfig = testConfig,
+ )
+
+ // Set up the quick access wallet config
+ val quickAccessWalletAffordanceConfigKey =
+ quickAccessWalletAffordanceConfig
+ .apply {
+ onTriggeredResult =
+ KeyguardQuickAffordanceConfig.OnTriggeredResult.StartActivity(
+ intent = Intent("action"),
+ canShowWhileLocked = false,
+ )
+ setState(
+ KeyguardQuickAffordanceConfig.LockScreenState.Visible(
+ icon = icon,
+ activationState = ActivationState.Active,
+ )
+ )
+ }
+ .let {
+ KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId() +
+ "::${quickAccessWalletAffordanceConfig.key}"
+ }
+
+ // onPreviewQuickAffordanceSelected should trigger the override with the quick access
+ // wallet quick affordance
+ underTest.onPreviewQuickAffordanceSelected(
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
+ BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET,
+ )
+ Truth.assertThat(latest()?.configKey).isEqualTo(quickAccessWalletAffordanceConfigKey)
+
+ // onClearPreviewQuickAffordances should make the default quick affordance shows again
+ underTest.onClearPreviewQuickAffordances()
+ Truth.assertThat(latest()?.configKey).isEqualTo(defaultConfigKey)
+ }
+
+ @Test
fun startButton_inPreviewMode_visibleEvenWhenKeyguardNotShowing() =
testScope.runTest {
underTest.onPreviewSlotSelected(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
@@ -445,7 +507,7 @@ class KeyguardQuickAffordancesCombinedViewModelTest : SysuiTestCase() {
}
@Test
- fun endButton_inHiglightedPreviewMode_dimmedWhenOtherIsSelected() =
+ fun endButton_inHighlightedPreviewMode_dimmedWhenOtherIsSelected() =
testScope.runTest {
underTest.onPreviewSlotSelected(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)
underTest.enablePreviewMode(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START, true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 63192f35ff40..95db95cd288b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -674,6 +674,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase {
}
@Test
+ @EnableFlags(NotificationContentAlphaOptimization.FLAG_NAME)
public void testForceResetSwipeStateDoesNothingIfTranslationIsZeroAndAlphaIsOne() {
doReturn(FAKE_ROW_WIDTH).when(mNotificationRow).getMeasuredWidth();
doReturn(0f).when(mNotificationRow).getTranslationX();
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt
index a0a39d14dcf6..63386d016a7a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/domain/interactor/AudioSlidersInteractorKosmos.kt
@@ -17,15 +17,17 @@
package com.android.systemui.volume.panel.component.volume.domain.interactor
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.volume.data.repository.audioRepository
+import com.android.systemui.volume.domain.interactor.audioModeInteractor
import com.android.systemui.volume.mediaOutputInteractor
val Kosmos.audioSlidersInteractor by
Kosmos.Fixture {
AudioSlidersInteractor(
- testScope.backgroundScope,
+ applicationCoroutineScope,
mediaOutputInteractor,
audioRepository,
+ audioModeInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt
index 45a291e0e401..6e848ce26d9b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/VolumeSlidersViewModelKosmos.kt
@@ -18,6 +18,7 @@ package com.android.systemui.volume.panel.component.volume.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
+import com.android.systemui.volume.domain.interactor.audioModeInteractor
import com.android.systemui.volume.mediaDeviceSessionInteractor
import com.android.systemui.volume.mediaOutputInteractor
import com.android.systemui.volume.panel.component.volume.domain.interactor.audioSlidersInteractor
@@ -32,6 +33,7 @@ val Kosmos.audioVolumeComponentViewModel by
mediaDeviceSessionInteractor,
audioStreamSliderViewModelFactory,
castVolumeSliderViewModelFactory,
+ audioModeInteractor,
audioSlidersInteractor,
)
}
diff --git a/ravenwood/tools/ravenizer-fake/Android.bp b/ravenwood/tools/ravenizer-fake/Android.bp
new file mode 100644
index 000000000000..7e2c407f2116
--- /dev/null
+++ b/ravenwood/tools/ravenizer-fake/Android.bp
@@ -0,0 +1,14 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+sh_binary_host {
+ name: "ravenizer",
+ src: "ravenizer",
+ visibility: ["//visibility:public"],
+}
diff --git a/ravenwood/tools/ravenizer-fake/ravenizer b/ravenwood/tools/ravenizer-fake/ravenizer
new file mode 100755
index 000000000000..84b3c8ee365e
--- /dev/null
+++ b/ravenwood/tools/ravenizer-fake/ravenizer
@@ -0,0 +1,31 @@
+#!/bin/bash
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# "Fake" ravenizer, which just copies the file.
+# We need it to add ravenizer support to Soong on AOSP,
+# when the actual ravenizer is not in AOSP yet.
+
+invalid_arg() {
+ echo "Ravenizer(fake): invalid args" 1>&2
+ exit 1
+}
+
+(( $# >= 4 )) || invalid_arg
+[[ "$1" == "--in-jar" ]] || invalid_arg
+[[ "$3" == "--out-jar" ]] || invalid_arg
+
+echo "Ravenizer(fake): copiyng $2 to $4"
+
+cp "$2" "$4"
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index 5c6f99a3e5a9..aa57e0b84a63 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -305,12 +305,8 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
mDelegatingState = new DelegatingState();
- mDetectingState = Flags.enableMagnificationMultipleFingerMultipleTapGesture()
- ? new DetectingStateWithMultiFinger(context)
- : new DetectingState(context);
- mViewportDraggingState = Flags.enableMagnificationMultipleFingerMultipleTapGesture()
- ? new ViewportDraggingStateWithMultiFinger()
- : new ViewportDraggingState();
+ mDetectingState = new DetectingState(context);
+ mViewportDraggingState = new ViewportDraggingState();
mPanningScalingState = new PanningScalingState(context);
mSinglePanningState = new SinglePanningState(context);
mFullScreenMagnificationVibrationHelper = fullScreenMagnificationVibrationHelper;
@@ -701,62 +697,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
}
- final class ViewportDraggingStateWithMultiFinger extends ViewportDraggingState {
- // LINT.IfChange(viewport_dragging_state_with_multi_finger)
- @Override
- public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags)
- throws GestureException {
- final int action = event.getActionMasked();
- switch (action) {
- case ACTION_POINTER_DOWN: {
- clearAndTransitToPanningScalingState();
- }
- break;
- case ACTION_MOVE: {
- if (event.getPointerCount() > 2) {
- throw new GestureException("Should have one pointer down.");
- }
- final float eventX = event.getX();
- final float eventY = event.getY();
- if (mFullScreenMagnificationController.magnificationRegionContains(
- mDisplayId, eventX, eventY)) {
- mFullScreenMagnificationController.setCenter(mDisplayId, eventX, eventY,
- /* animate */ mLastMoveOutsideMagnifiedRegion,
- AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
- mLastMoveOutsideMagnifiedRegion = false;
- } else {
- mLastMoveOutsideMagnifiedRegion = true;
- }
- }
- break;
-
- case ACTION_UP:
- case ACTION_CANCEL: {
- // If mScaleToRecoverAfterDraggingEnd >= 1.0, the dragging state is triggered
- // by zoom in temporary, and the magnifier needs to recover to original scale
- // after exiting dragging state.
- // Otherwise, the magnifier should be disabled.
- if (mScaleToRecoverAfterDraggingEnd >= 1.0f) {
- zoomToScale(mScaleToRecoverAfterDraggingEnd, event.getX(),
- event.getY());
- } else {
- zoomOff();
- }
- clear();
- mScaleToRecoverAfterDraggingEnd = Float.NaN;
- transitionTo(mDetectingState);
- }
- break;
-
- case ACTION_DOWN: {
- throw new GestureException(
- "Unexpected event type: " + MotionEvent.actionToString(action));
- }
- }
- }
- // LINT.ThenChange(:viewport_dragging_state)
- }
-
/**
* This class handles motion events when the event dispatcher has
* determined that the user is performing a single-finger drag of the
@@ -777,7 +717,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
protected boolean mLastMoveOutsideMagnifiedRegion;
- // LINT.IfChange(viewport_dragging_state)
@Override
public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags)
throws GestureException {
@@ -788,7 +727,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
break;
case ACTION_MOVE: {
- if (event.getPointerCount() != 1) {
+ if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
+ if (event.getPointerCount() > 2) {
+ throw new GestureException("Should have at most two pointers down.");
+ }
+ } else if (event.getPointerCount() != 1) {
throw new GestureException("Should have one pointer down.");
}
final float eventX = event.getX();
@@ -823,14 +766,20 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
break;
- case ACTION_DOWN:
case ACTION_POINTER_UP: {
+ if (!Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
+ throw new GestureException(
+ "Unexpected event type: " + MotionEvent.actionToString(action));
+ }
+ }
+ break;
+
+ case ACTION_DOWN: {
throw new GestureException(
"Unexpected event type: " + MotionEvent.actionToString(action));
}
}
}
- // LINT.ThenChange(:viewport_dragging_state_with_multi_finger)
private boolean isAlwaysOnMagnificationEnabled() {
return mFullScreenMagnificationController.isAlwaysOnMagnificationEnabled();
@@ -916,270 +865,31 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
}
- final class DetectingStateWithMultiFinger extends DetectingState {
- private static final int TWO_FINGER_GESTURE_MAX_TAPS = 2;
- // A flag set to true when two fingers have touched down.
- // Used to indicate what next finger action should be.
- private boolean mIsTwoFingerCountReached = false;
- // A tap counts when two fingers are down and up once.
- private int mCompletedTapCount = 0;
- DetectingStateWithMultiFinger(Context context) {
- super(context);
- }
-
- // LINT.IfChange(detecting_state_with_multi_finger)
- @Override
- public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
- cacheDelayedMotionEvent(event, rawEvent, policyFlags);
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_DOWN: {
- mLastDetectingDownEventTime = event.getDownTime();
- mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
-
- mFirstPointerDownLocation.set(event.getX(), event.getY());
-
- if (!mFullScreenMagnificationController.magnificationRegionContains(
- mDisplayId, event.getX(), event.getY())) {
-
- transitionToDelegatingStateAndClear();
-
- } else if (isMultiTapTriggered(2 /* taps */)) {
-
- // 3tap and hold
- afterLongTapTimeoutTransitionToDraggingState(event);
-
- } else if (isTapOutOfDistanceSlop()) {
-
- transitionToDelegatingStateAndClear();
-
- } else if (mDetectSingleFingerTripleTap
- || mDetectTwoFingerTripleTap
- // If activated, delay an ACTION_DOWN for mMultiTapMaxDelay
- // to ensure reachability of
- // STATE_PANNING_SCALING(triggerable with ACTION_POINTER_DOWN)
- || isActivated()) {
-
- afterMultiTapTimeoutTransitionToDelegatingState();
-
- } else {
-
- // Delegate pending events without delay
- transitionToDelegatingStateAndClear();
- }
- }
- break;
- case ACTION_POINTER_DOWN: {
- mIsTwoFingerCountReached = mDetectTwoFingerTripleTap
- && event.getPointerCount() == 2;
- mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
-
- if (event.getPointerCount() == 2) {
- if (isMultiFingerMultiTapTriggered(
- TWO_FINGER_GESTURE_MAX_TAPS - 1, event)) {
- // 3tap and hold
- afterLongTapTimeoutTransitionToDraggingState(event);
- } else {
- if (mDetectTwoFingerTripleTap) {
- // If mDetectTwoFingerTripleTap, delay transition to the delegating
- // state for mMultiTapMaxDelay to ensure reachability of
- // multi finger multi tap
- afterMultiTapTimeoutTransitionToDelegatingState();
- }
-
- if (isActivated()) {
- // If activated, delay transition to the panning scaling
- // state for tap timeout to ensure reachability of
- // multi finger multi tap
- storePointerDownLocation(mSecondPointerDownLocation, event);
- mHandler.sendEmptyMessageDelayed(
- MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE,
- ViewConfiguration.getTapTimeout());
- }
- }
- } else {
- transitionToDelegatingStateAndClear();
- }
- }
- break;
- case ACTION_POINTER_UP: {
- // If it is a two-finger gesture, do not transition to the delegating state
- // to ensure the reachability of
- // the two-finger triple tap (triggerable with ACTION_MOVE and ACTION_UP)
- if (!mIsTwoFingerCountReached) {
- transitionToDelegatingStateAndClear();
- }
- }
- break;
- case ACTION_MOVE: {
- if (isFingerDown()
- && distance(mLastDown, /* move */ event) > mSwipeMinDistance) {
- // Swipe detected - transition immediately
-
- // For convenience, viewport dragging takes precedence
- // over insta-delegating on 3tap&swipe
- // (which is a rare combo to be used aside from magnification)
- if (isMultiTapTriggered(2 /* taps */) && event.getPointerCount() == 1) {
- transitionToViewportDraggingStateAndClear(event);
- } else if (isMultiFingerMultiTapTriggered(
- TWO_FINGER_GESTURE_MAX_TAPS - 1, event)
- && event.getPointerCount() == 2) {
- transitionToViewportDraggingStateAndClear(event);
- } else if (isActivated() && event.getPointerCount() == 2) {
- if (mOverscrollHandler != null
- && overscrollState(event, mFirstPointerDownLocation)
- == OVERSCROLL_VERTICAL_EDGE) {
- transitionToDelegatingStateAndClear();
- } else {
- //Primary pointer is swiping, so transit to PanningScalingState
- transitToPanningScalingStateAndClear();
- }
- } else if (mOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()
- && isActivated()
- && event.getPointerCount() == 1) {
- if (mOverscrollHandler != null
- && overscrollState(event, mFirstPointerDownLocation)
- == OVERSCROLL_VERTICAL_EDGE) {
- transitionToDelegatingStateAndClear();
- } else if (overscrollState(event, mFirstPointerDownLocation)
- != OVERSCROLL_NONE) {
- transitionToDelegatingStateAndClear();
- } else {
- transitToSinglePanningStateAndClear();
- }
- } else if (!mIsTwoFingerCountReached) {
- // If it is a two-finger gesture, do not transition to the
- // delegating state to ensure the reachability of
- // the two-finger triple tap (triggerable with ACTION_UP)
- transitionToDelegatingStateAndClear();
- }
- } else if (isActivated() && pointerDownValid(mSecondPointerDownLocation)
- && distanceClosestPointerToPoint(
- mSecondPointerDownLocation, /* move */ event) > mSwipeMinDistance) {
- // Second pointer is swiping, so transit to PanningScalingState
- // Delay an ACTION_MOVE for tap timeout to ensure it is not trigger from
- // multi finger multi tap
- storePointerDownLocation(mSecondPointerDownLocation, event);
- mHandler.sendEmptyMessageDelayed(
- MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE,
- ViewConfiguration.getTapTimeout());
- }
- }
- break;
- case ACTION_UP: {
-
- mHandler.removeMessages(MESSAGE_ON_TRIPLE_TAP_AND_HOLD);
- mHandler.removeMessages(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE);
-
- if (!mFullScreenMagnificationController.magnificationRegionContains(
- mDisplayId, event.getX(), event.getY())) {
- transitionToDelegatingStateAndClear();
-
- } else if (isMultiFingerMultiTapTriggered(TWO_FINGER_GESTURE_MAX_TAPS, event)) {
- // Placing multiple fingers before a single finger, because achieving a
- // multi finger multi tap also means achieving a single finger triple tap
- onTripleTap(event);
-
- } else if (isMultiTapTriggered(3 /* taps */)) {
- onTripleTap(/* up */ event);
-
- } else if (
- // Possible to be false on: 3tap&drag -> scale -> PTR_UP -> UP
- isFingerDown()
- //TODO long tap should never happen here
- && ((timeBetween(mLastDown, mLastUp) >= mLongTapMinDelay)
- || (distance(mLastDown, mLastUp) >= mSwipeMinDistance))
- // If it is a two-finger but not reach 3 tap, do not transition to the
- // delegating state to ensure the reachability of the triple tap
- && mCompletedTapCount == 0) {
- transitionToDelegatingStateAndClear();
-
- }
- }
- break;
- }
- }
- // LINT.ThenChange(:detecting_state)
-
- @Override
- public void clear() {
- mCompletedTapCount = 0;
- setShortcutTriggered(false);
- removePendingDelayedMessages();
- clearDelayedMotionEvents();
- mFirstPointerDownLocation.set(Float.NaN, Float.NaN);
- mSecondPointerDownLocation.set(Float.NaN, Float.NaN);
- }
-
- private boolean isMultiFingerMultiTapTriggered(int targetTapCount, MotionEvent event) {
- if (event.getActionMasked() == ACTION_UP && mIsTwoFingerCountReached) {
- mCompletedTapCount++;
- mIsTwoFingerCountReached = false;
- }
-
- if (mDetectTwoFingerTripleTap && mCompletedTapCount > TWO_FINGER_GESTURE_MAX_TAPS - 1) {
- final boolean enabled = !isActivated();
- mMagnificationLogger.logMagnificationTwoFingerTripleTap(enabled);
- }
- return mDetectTwoFingerTripleTap && mCompletedTapCount == targetTapCount;
- }
-
- void transitionToDelegatingStateAndClear() {
- mCompletedTapCount = 0;
- transitionTo(mDelegatingState);
- sendDelayedMotionEvents();
- removePendingDelayedMessages();
- mFirstPointerDownLocation.set(Float.NaN, Float.NaN);
- mSecondPointerDownLocation.set(Float.NaN, Float.NaN);
- }
-
- void transitionToViewportDraggingStateAndClear(MotionEvent down) {
-
- if (DEBUG_DETECTING) Slog.i(mLogTag, "onTripleTapAndHold()");
- final boolean shortcutTriggered = mShortcutTriggered;
-
- // Only log the 3tap and hold event
- if (!shortcutTriggered) {
- final boolean enabled = !isActivated();
- if (mCompletedTapCount == TWO_FINGER_GESTURE_MAX_TAPS - 1) {
- // Two finger triple tap and hold
- mMagnificationLogger.logMagnificationTwoFingerTripleTap(enabled);
- } else {
- // Triple tap and hold also belongs to triple tap event
- mMagnificationLogger.logMagnificationTripleTap(enabled);
- }
- }
- clear();
-
- mViewportDraggingState.prepareForZoomInTemporary(shortcutTriggered);
- zoomInTemporary(down.getX(), down.getY(), shortcutTriggered);
- transitionTo(mViewportDraggingState);
- }
- }
-
/**
* This class handles motion events when the event dispatch has not yet
* determined what the user is doing. It watches for various tap events.
*/
class DetectingState implements State, Handler.Callback {
- protected static final int MESSAGE_ON_TRIPLE_TAP_AND_HOLD = 1;
- protected static final int MESSAGE_TRANSITION_TO_DELEGATING_STATE = 2;
- protected static final int MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE = 3;
+ private static final int MESSAGE_ON_TRIPLE_TAP_AND_HOLD = 1;
+ private static final int MESSAGE_TRANSITION_TO_DELEGATING_STATE = 2;
+ private static final int MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE = 3;
final int mLongTapMinDelay;
final int mSwipeMinDistance;
final int mMultiTapMaxDelay;
final int mMultiTapMaxDistance;
+ @Nullable final TwoFingerDoubleTapHandler mTwoFingerDoubleTapHandler;
- protected MotionEventInfo mDelayedEventQueue;
- protected MotionEvent mLastDown;
- protected MotionEvent mPreLastDown;
- protected MotionEvent mLastUp;
- protected MotionEvent mPreLastUp;
+ private MotionEventInfo mDelayedEventQueue;
+ private MotionEvent mLastDown;
+ private MotionEvent mPreLastDown;
+ private MotionEvent mLastUp;
+ private MotionEvent mPreLastUp;
- protected PointF mFirstPointerDownLocation = new PointF(Float.NaN, Float.NaN);
- protected PointF mSecondPointerDownLocation = new PointF(Float.NaN, Float.NaN);
- protected long mLastDetectingDownEventTime;
+ private PointF mFirstPointerDownLocation = new PointF(Float.NaN, Float.NaN);
+ private PointF mSecondPointerDownLocation = new PointF(Float.NaN, Float.NaN);
+ private long mLastDetectingDownEventTime;
@VisibleForTesting boolean mShortcutTriggered;
@@ -1191,6 +901,9 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
MagnificationGestureMatcher.getMagnificationMultiTapTimeout(context);
mSwipeMinDistance = ViewConfiguration.get(context).getScaledTouchSlop();
mMultiTapMaxDistance = ViewConfiguration.get(context).getScaledDoubleTapSlop();
+ mTwoFingerDoubleTapHandler =
+ Flags.enableMagnificationMultipleFingerMultipleTapGesture()
+ ? new TwoFingerDoubleTapHandler() : null;
}
@Override
@@ -1218,7 +931,6 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
return true;
}
- // LINT.IfChange(detecting_state)
@Override
public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
cacheDelayedMotionEvent(event, rawEvent, policyFlags);
@@ -1244,6 +956,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
transitionToDelegatingStateAndClear();
} else if (mDetectSingleFingerTripleTap
+ || (mTwoFingerDoubleTapHandler != null && mDetectTwoFingerTripleTap)
// If activated, delay an ACTION_DOWN for mMultiTapMaxDelay
// to ensure reachability of
// STATE_PANNING_SCALING(triggerable with ACTION_POINTER_DOWN)
@@ -1259,6 +972,12 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
break;
case ACTION_POINTER_DOWN: {
+ if (mTwoFingerDoubleTapHandler != null) {
+ mTwoFingerDoubleTapHandler.onPointerDown(event);
+ break;
+ }
+
+ // LINT.IfChange(action_pointer_down)
if (isActivated() && event.getPointerCount() == 2) {
storePointerDownLocation(mSecondPointerDownLocation, event);
mHandler.sendEmptyMessageDelayed(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE,
@@ -1266,13 +985,26 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
} else {
transitionToDelegatingStateAndClear();
}
+ // LINT.ThenChange(:action_pointer_down_with_multi_finger)
}
break;
case ACTION_POINTER_UP: {
+ if (mTwoFingerDoubleTapHandler != null) {
+ mTwoFingerDoubleTapHandler.onPointerUp();
+ break;
+ }
+ // LINT.IfChange(action_pointer_up)
transitionToDelegatingStateAndClear();
+ // LINT.ThenChange(:action_pointer_up_with_multi_finger)
}
break;
case ACTION_MOVE: {
+ if (mTwoFingerDoubleTapHandler != null) {
+ mTwoFingerDoubleTapHandler.onMove(event);
+ break;
+ }
+
+ // LINT.IfChange(action_move)
if (isFingerDown()
&& distance(mLastDown, /* move */ event) > mSwipeMinDistance) {
// Swipe detected - transition immediately
@@ -1313,12 +1045,20 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
//Second pointer is swiping, so transit to PanningScalingState
transitToPanningScalingStateAndClear();
}
+ // LINT.ThenChange(:action_move_with_multi_finger)
}
break;
case ACTION_UP: {
mHandler.removeMessages(MESSAGE_ON_TRIPLE_TAP_AND_HOLD);
+ if (mTwoFingerDoubleTapHandler != null) {
+ mHandler.removeMessages(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE);
+ mTwoFingerDoubleTapHandler.onUp(event);
+ break;
+ }
+
+ // LINT.IfChange(action_up)
if (!mFullScreenMagnificationController.magnificationRegionContains(
mDisplayId, event.getX(), event.getY())) {
transitionToDelegatingStateAndClear();
@@ -1335,11 +1075,11 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
transitionToDelegatingStateAndClear();
}
+ // LINT.ThenChange(:action_up_with_multi_finger)
}
break;
}
}
- // LINT.ThenChange(:detecting_state_with_multi_finger)
protected void storePointerDownLocation(PointF pointerDownLocation, MotionEvent event) {
final int index = event.getActionIndex();
@@ -1425,6 +1165,9 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
@Override
public void clear() {
+ if (mTwoFingerDoubleTapHandler != null) {
+ mTwoFingerDoubleTapHandler.mCompletedTapCount = 0;
+ }
setShortcutTriggered(false);
removePendingDelayedMessages();
clearDelayedMotionEvents();
@@ -1501,9 +1244,13 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
void transitionToDelegatingStateAndClear() {
+ if (mTwoFingerDoubleTapHandler != null) {
+ mTwoFingerDoubleTapHandler.mCompletedTapCount = 0;
+ }
transitionTo(mDelegatingState);
sendDelayedMotionEvents();
removePendingDelayedMessages();
+ mFirstPointerDownLocation.set(Float.NaN, Float.NaN);
mSecondPointerDownLocation.set(Float.NaN, Float.NaN);
}
@@ -1543,9 +1290,15 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
// Only log the 3tap and hold event
if (!shortcutTriggered) {
- // Triple tap and hold also belongs to triple tap event
final boolean enabled = !isActivated();
- mMagnificationLogger.logMagnificationTripleTap(enabled);
+ if (mTwoFingerDoubleTapHandler != null
+ && mTwoFingerDoubleTapHandler.shouldLogTwoFingerDoubleTap()) {
+ // Two finger double tap and hold
+ mMagnificationLogger.logMagnificationTwoFingerTripleTap(enabled);
+ } else {
+ // Triple tap and hold also belongs to triple tap event
+ mMagnificationLogger.logMagnificationTripleTap(enabled);
+ }
}
clear();
@@ -1604,6 +1357,173 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
}
return false;
}
+
+ final class TwoFingerDoubleTapHandler {
+ private static final int TWO_FINGER_GESTURE_MAX_TAPS = 2;
+ // A tap counts when two fingers are down and up once.
+ private int mCompletedTapCount;
+ // A flag set to true when two fingers have touched down.
+ // Used to indicate what next finger action should be.
+ private boolean mIsTwoFingerCountReached;
+
+ TwoFingerDoubleTapHandler() {
+ mCompletedTapCount = 0;
+ mIsTwoFingerCountReached = false;
+ }
+
+ private void onPointerDown(MotionEvent event) {
+ mIsTwoFingerCountReached = mDetectTwoFingerTripleTap
+ && event.getPointerCount() == 2;
+ mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
+
+ // LINT.IfChange(action_pointer_down_with_multi_finger)
+ if (event.getPointerCount() == 2) {
+ if (isMultiFingerMultiTapTriggered(
+ TWO_FINGER_GESTURE_MAX_TAPS - 1, event)) {
+ // 3tap and hold
+ afterLongTapTimeoutTransitionToDraggingState(event);
+ } else {
+ if (mDetectTwoFingerTripleTap) {
+ // If mDetectTwoFingerTripleTap, delay transition to the delegating
+ // state for mMultiTapMaxDelay to ensure reachability of
+ // multi finger multi tap
+ afterMultiTapTimeoutTransitionToDelegatingState();
+ }
+
+ if (isActivated()) {
+ // If activated, delay transition to the panning scaling
+ // state for tap timeout to ensure reachability of
+ // multi finger multi tap
+ storePointerDownLocation(mSecondPointerDownLocation, event);
+ mHandler.sendEmptyMessageDelayed(
+ MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE,
+ ViewConfiguration.getTapTimeout());
+ }
+ }
+ } else {
+ transitionToDelegatingStateAndClear();
+ }
+ // LINT.ThenChange(:action_pointer_down)
+ }
+
+ private void onMove(MotionEvent event) {
+ // LINT.IfChange(action_move_with_multi_finger)
+ if (isFingerDown()
+ && distance(mLastDown, /* move */ event) > mSwipeMinDistance) {
+ // Swipe detected - transition immediately
+
+ // For convenience, viewport dragging takes precedence
+ // over insta-delegating on 3tap&swipe
+ // (which is a rare combo to be used aside from magnification)
+ if (isMultiTapTriggered(2 /* taps */) && event.getPointerCount() == 1) {
+ transitionToViewportDraggingStateAndClear(event);
+ } else if (isMultiFingerMultiTapTriggered(
+ TWO_FINGER_GESTURE_MAX_TAPS - 1, event)
+ && event.getPointerCount() == 2) {
+ transitionToViewportDraggingStateAndClear(event);
+ } else if (isActivated() && event.getPointerCount() == 2) {
+ if (mOverscrollHandler != null
+ && overscrollState(event, mFirstPointerDownLocation)
+ == OVERSCROLL_VERTICAL_EDGE) {
+ transitionToDelegatingStateAndClear();
+ } else {
+ //Primary pointer is swiping, so transit to PanningScalingState
+ transitToPanningScalingStateAndClear();
+ }
+ } else if (mOneFingerPanningSettingsProvider.isOneFingerPanningEnabled()
+ && isActivated()
+ && event.getPointerCount() == 1) {
+ if (mOverscrollHandler != null
+ && overscrollState(event, mFirstPointerDownLocation)
+ == OVERSCROLL_VERTICAL_EDGE) {
+ transitionToDelegatingStateAndClear();
+ } else if (overscrollState(event, mFirstPointerDownLocation)
+ != OVERSCROLL_NONE) {
+ transitionToDelegatingStateAndClear();
+ } else {
+ transitToSinglePanningStateAndClear();
+ }
+ } else if (!mIsTwoFingerCountReached) {
+ // If it is a two-finger gesture, do not transition to the
+ // delegating state to ensure the reachability of
+ // the two-finger triple tap (triggerable with ACTION_UP)
+ transitionToDelegatingStateAndClear();
+ }
+ } else if (isActivated() && pointerDownValid(mSecondPointerDownLocation)
+ && distanceClosestPointerToPoint(
+ mSecondPointerDownLocation, /* move */ event) > mSwipeMinDistance) {
+ // Second pointer is swiping, so transit to PanningScalingState
+ // Delay an ACTION_MOVE for tap timeout to ensure it is not trigger from
+ // multi finger multi tap
+ storePointerDownLocation(mSecondPointerDownLocation, event);
+ mHandler.sendEmptyMessageDelayed(
+ MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE,
+ ViewConfiguration.getTapTimeout());
+ }
+ // LINT.ThenChange(:action_move)
+ }
+
+ private void onPointerUp() {
+ // If it is a two-finger gesture, do not transition to the delegating state
+ // to ensure the reachability of
+ // the two-finger triple tap (triggerable with ACTION_MOVE and ACTION_UP)
+ // LINT.IfChange(action_pointer_up_with_multi_finger)
+ if (!mIsTwoFingerCountReached) {
+ transitionToDelegatingStateAndClear();
+ }
+ // LINT.ThenChange(:action_pointer_up)
+ }
+
+ private void onUp(MotionEvent event) {
+ // LINT.IfChange(action_up_with_multi_finger)
+ if (!mFullScreenMagnificationController.magnificationRegionContains(
+ mDisplayId, event.getX(), event.getY())) {
+ transitionToDelegatingStateAndClear();
+
+ } else if (isMultiFingerMultiTapTriggered(
+ TWO_FINGER_GESTURE_MAX_TAPS, event)) {
+ // Placing multiple fingers before a single finger, because achieving a
+ // multi finger multi tap also means achieving a single finger
+ // triple tap
+ onTripleTap(event);
+
+ } else if (isMultiTapTriggered(3 /* taps */)) {
+ onTripleTap(/* up */ event);
+
+ } else if (
+ // Possible to be false on: 3tap&drag -> scale -> PTR_UP -> UP
+ isFingerDown()
+ //TODO long tap should never happen here
+ && ((timeBetween(mLastDown, mLastUp) >= mLongTapMinDelay)
+ || (distance(mLastDown, mLastUp) >= mSwipeMinDistance))
+ // If it is a two-finger but not reach 3 tap, do not
+ // transition to the delegating state to ensure the
+ // reachability of the triple tap
+ && mCompletedTapCount == 0) {
+ transitionToDelegatingStateAndClear();
+ }
+ // LINT.ThenChange(:action_up)
+ }
+
+ private boolean isMultiFingerMultiTapTriggered(int targetTapCount, MotionEvent event) {
+ if (event.getActionMasked() == ACTION_UP && mIsTwoFingerCountReached) {
+ mCompletedTapCount++;
+ mIsTwoFingerCountReached = false;
+ }
+
+ if (mDetectTwoFingerTripleTap
+ && mCompletedTapCount > TWO_FINGER_GESTURE_MAX_TAPS - 1) {
+ final boolean enabled = !isActivated();
+ mMagnificationLogger.logMagnificationTwoFingerTripleTap(enabled);
+ }
+ return mDetectTwoFingerTripleTap && mCompletedTapCount == targetTapCount;
+ }
+
+ private boolean shouldLogTwoFingerDoubleTap() {
+ return mCompletedTapCount
+ == TwoFingerDoubleTapHandler.TWO_FINGER_GESTURE_MAX_TAPS - 1;
+ }
+ }
}
private void zoomInTemporary(float centerX, float centerY, boolean shortcutTriggered) {
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 2db54435199b..1be352e8e3da 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -137,11 +137,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
| DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH
| DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_FOCUS;
- private static final int DEFAULT_VIRTUAL_DISPLAY_FLAGS_PRE_VIC =
- DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
- | DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT
- | DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
-
private static final String PERSISTENT_ID_PREFIX_CDM_ASSOCIATION = "companion:";
/**
@@ -373,9 +368,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
}
int flags = DEFAULT_VIRTUAL_DISPLAY_FLAGS;
- if (!Flags.consistentDisplayFlags()) {
- flags |= DEFAULT_VIRTUAL_DISPLAY_FLAGS_PRE_VIC;
- }
if (mParams.getLockState() == VirtualDeviceParams.LOCK_STATE_ALWAYS_UNLOCKED) {
flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED;
}
@@ -1254,10 +1246,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
// as the virtual display doesn't have any focused windows. Hence, call this for
// associating any input device to the source display if the input device emits any key events.
private int getTargetDisplayIdForInput(int displayId) {
- if (!Flags.interactiveScreenMirror()) {
- return displayId;
- }
-
DisplayManagerInternal displayManager = LocalServices.getService(
DisplayManagerInternal.class);
int mirroredDisplayId = displayManager.getDisplayIdToMirror(displayId);
@@ -1313,9 +1301,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
int displayId;
displayId = mDisplayManagerInternal.createVirtualDisplay(virtualDisplayConfig, callback,
this, gwpc, packageName);
- gwpc.setDisplayId(displayId, /* isMirrorDisplay= */ Flags.interactiveScreenMirror()
- && mDisplayManagerInternal.getDisplayIdToMirror(displayId)
- != Display.INVALID_DISPLAY);
+ boolean isMirrorDisplay =
+ mDisplayManagerInternal.getDisplayIdToMirror(displayId) != Display.INVALID_DISPLAY;
+ gwpc.setDisplayId(displayId, isMirrorDisplay);
boolean showPointer;
synchronized (mVirtualDeviceLock) {
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 08153847df88..e84250dff028 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -309,13 +309,14 @@ public class PackageWatchdog {
*/
public void registerHealthObserver(PackageHealthObserver observer) {
synchronized (mLock) {
- ObserverInternal internalObserver = mAllObservers.get(observer.getName());
+ ObserverInternal internalObserver = mAllObservers.get(observer.getUniqueIdentifier());
if (internalObserver != null) {
internalObserver.registeredObserver = observer;
} else {
- internalObserver = new ObserverInternal(observer.getName(), new ArrayList<>());
+ internalObserver = new ObserverInternal(observer.getUniqueIdentifier(),
+ new ArrayList<>());
internalObserver.registeredObserver = observer;
- mAllObservers.put(observer.getName(), internalObserver);
+ mAllObservers.put(observer.getUniqueIdentifier(), internalObserver);
syncState("added new observer");
}
}
@@ -342,12 +343,12 @@ public class PackageWatchdog {
public void startObservingHealth(PackageHealthObserver observer, List<String> packageNames,
long durationMs) {
if (packageNames.isEmpty()) {
- Slog.wtf(TAG, "No packages to observe, " + observer.getName());
+ Slog.wtf(TAG, "No packages to observe, " + observer.getUniqueIdentifier());
return;
}
if (durationMs < 1) {
Slog.wtf(TAG, "Invalid duration " + durationMs + "ms for observer "
- + observer.getName() + ". Not observing packages " + packageNames);
+ + observer.getUniqueIdentifier() + ". Not observing packages " + packageNames);
durationMs = DEFAULT_OBSERVING_DURATION_MS;
}
@@ -374,14 +375,14 @@ public class PackageWatchdog {
syncState("observing new packages");
synchronized (mLock) {
- ObserverInternal oldObserver = mAllObservers.get(observer.getName());
+ ObserverInternal oldObserver = mAllObservers.get(observer.getUniqueIdentifier());
if (oldObserver == null) {
- Slog.d(TAG, observer.getName() + " started monitoring health "
+ Slog.d(TAG, observer.getUniqueIdentifier() + " started monitoring health "
+ "of packages " + packageNames);
- mAllObservers.put(observer.getName(),
- new ObserverInternal(observer.getName(), packages));
+ mAllObservers.put(observer.getUniqueIdentifier(),
+ new ObserverInternal(observer.getUniqueIdentifier(), packages));
} else {
- Slog.d(TAG, observer.getName() + " added the following "
+ Slog.d(TAG, observer.getUniqueIdentifier() + " added the following "
+ "packages to monitor " + packageNames);
oldObserver.updatePackagesLocked(packages);
}
@@ -405,9 +406,9 @@ public class PackageWatchdog {
public void unregisterHealthObserver(PackageHealthObserver observer) {
mLongTaskHandler.post(() -> {
synchronized (mLock) {
- mAllObservers.remove(observer.getName());
+ mAllObservers.remove(observer.getUniqueIdentifier());
}
- syncState("unregistering observer: " + observer.getName());
+ syncState("unregistering observer: " + observer.getUniqueIdentifier());
});
}
@@ -781,7 +782,7 @@ public class PackageWatchdog {
* Identifier for the observer, should not change across device updates otherwise the
* watchdog may drop observing packages with the old name.
*/
- String getName();
+ String getUniqueIdentifier();
/**
* An observer will not be pruned if this is set, even if the observer is not explicitly
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index c2cb5e90ca58..bba97fad0fc9 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -917,7 +917,7 @@ public class RescueParty {
}
@Override
- public String getName() {
+ public String getUniqueIdentifier() {
return NAME;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 91b549c9a04b..68d92218c01b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15312,12 +15312,17 @@ public class ActivityManagerService extends IActivityManager.Stub
final int cookie = traceBroadcastIntentBegin(intent, resultTo, ordered, sticky,
callingUid, realCallingUid, userId);
try {
+ final BroadcastSentEventRecord broadcastSentEventRecord =
+ new BroadcastSentEventRecord();
final int res = broadcastIntentLockedTraced(callerApp, callerPackage, callerFeatureId,
intent, resolvedType, resultToApp, resultTo, resultCode, resultData,
resultExtras, requiredPermissions, excludedPermissions, excludedPackages,
appOp, BroadcastOptions.fromBundleNullable(bOptions), ordered, sticky,
callingPid, callingUid, realCallingUid, realCallingPid, userId,
- backgroundStartPrivileges, broadcastAllowList, filterExtrasForReceiver);
+ backgroundStartPrivileges, broadcastAllowList, filterExtrasForReceiver,
+ broadcastSentEventRecord);
+ broadcastSentEventRecord.setResult(res);
+ broadcastSentEventRecord.logToStatsd();
return res;
} finally {
traceBroadcastIntentEnd(cookie);
@@ -15365,7 +15370,8 @@ public class ActivityManagerService extends IActivityManager.Stub
int callingUid, int realCallingUid, int realCallingPid, int userId,
BackgroundStartPrivileges backgroundStartPrivileges,
@Nullable int[] broadcastAllowList,
- @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver) {
+ @Nullable BiFunction<Integer, Bundle, Bundle> filterExtrasForReceiver,
+ @NonNull BroadcastSentEventRecord broadcastSentEventRecord) {
// Ensure all internal loopers are registered for idle checks
BroadcastLoopers.addMyLooper();
@@ -15398,6 +15404,17 @@ public class ActivityManagerService extends IActivityManager.Stub
}
intent = new Intent(intent);
+ broadcastSentEventRecord.setIntent(intent);
+ broadcastSentEventRecord.setOriginalIntentFlags(intent.getFlags());
+ broadcastSentEventRecord.setSenderUid(callingUid);
+ broadcastSentEventRecord.setRealSenderUid(realCallingUid);
+ broadcastSentEventRecord.setSticky(sticky);
+ broadcastSentEventRecord.setOrdered(ordered);
+ broadcastSentEventRecord.setResultRequested(resultTo != null);
+ final int callerAppProcessState = getRealProcessStateLocked(callerApp, realCallingPid);
+ broadcastSentEventRecord.setSenderProcState(callerAppProcessState);
+ broadcastSentEventRecord.setSenderUidState(getRealUidStateLocked(callerApp,
+ realCallingPid));
final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
// Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
@@ -15891,7 +15908,6 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
- final int callerAppProcessState = getRealProcessStateLocked(callerApp, realCallingPid);
// Add to the sticky list if requested.
if (sticky) {
if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
@@ -16131,6 +16147,7 @@ public class ActivityManagerService extends IActivityManager.Stub
ordered, sticky, false, userId,
backgroundStartPrivileges, timeoutExempt, filterExtrasForReceiver,
callerAppProcessState);
+ broadcastSentEventRecord.setBroadcastRecord(r);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);
queue.enqueueBroadcastLocked(r);
@@ -16187,6 +16204,22 @@ public class ActivityManagerService extends IActivityManager.Stub
return PROCESS_STATE_NONEXISTENT;
}
+ @GuardedBy("this")
+ private int getRealUidStateLocked(ProcessRecord app, int pid) {
+ if (app == null) {
+ synchronized (mPidsSelfLocked) {
+ app = mPidsSelfLocked.get(pid);
+ }
+ }
+ if (app != null && app.getThread() != null && !app.isKilled()) {
+ final UidRecord uidRecord = app.getUidRecord();
+ if (uidRecord != null) {
+ return uidRecord.getCurProcState();
+ }
+ }
+ return PROCESS_STATE_NONEXISTENT;
+ }
+
@VisibleForTesting
ArrayList<StickyBroadcast> getStickyBroadcastsForTest(String action, int userId) {
synchronized (mStickyBroadcasts) {
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index edb04c5c00bc..f908c67d7ec9 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -53,6 +53,7 @@ import android.os.Bundle;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.ArrayMap;
+import android.util.IntArray;
import android.util.PrintWriterPrinter;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -940,6 +941,46 @@ final class BroadcastRecord extends Binder {
return type;
}
+ int[] calculateTypesForLogging() {
+ final IntArray types = new IntArray();
+ if (isForeground()) {
+ types.add(BROADCAST_TYPE_FOREGROUND);
+ } else {
+ types.add(BROADCAST_TYPE_BACKGROUND);
+ }
+ if (alarm) {
+ types.add(BROADCAST_TYPE_ALARM);
+ }
+ if (interactive) {
+ types.add(BROADCAST_TYPE_INTERACTIVE);
+ }
+ if (ordered) {
+ types.add(BROADCAST_TYPE_ORDERED);
+ }
+ if (prioritized) {
+ types.add(BROADCAST_TYPE_PRIORITIZED);
+ }
+ if (resultTo != null) {
+ types.add(BROADCAST_TYPE_RESULT_TO);
+ }
+ if (deferUntilActive) {
+ types.add(BROADCAST_TYPE_DEFERRABLE_UNTIL_ACTIVE);
+ }
+ if (pushMessage) {
+ types.add(BROADCAST_TYPE_PUSH_MESSAGE);
+ }
+ if (pushMessageOverQuota) {
+ types.add(BROADCAST_TYPE_PUSH_MESSAGE_OVER_QUOTA);
+ }
+ if (sticky) {
+ types.add(BROADCAST_TYPE_STICKY);
+ }
+ if (initialSticky) {
+ types.add(BROADCAST_TYPE_INITIAL_STICKY);
+ }
+ return types.toArray();
+ }
+
public BroadcastRecord maybeStripForHistory() {
if (!intent.canStripForHistory()) {
return this;
diff --git a/services/core/java/com/android/server/am/BroadcastSentEventRecord.java b/services/core/java/com/android/server/am/BroadcastSentEventRecord.java
new file mode 100644
index 000000000000..f2ac6d52b0c0
--- /dev/null
+++ b/services/core/java/com/android/server/am/BroadcastSentEventRecord.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.app.AppProtoEnums.BROADCAST_TYPE_ORDERED;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_RESULT_TO;
+import static android.app.AppProtoEnums.BROADCAST_TYPE_STICKY;
+
+import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT;
+import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__FAILED_STICKY_CANT_HAVE_PERMISSION;
+import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__FAILED_USER_STOPPED;
+import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__SUCCESS;
+import static com.android.internal.util.FrameworkStatsLog.BROADCAST_SENT__RESULT__UNKNOWN;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.Intent;
+import android.util.IntArray;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+final class BroadcastSentEventRecord {
+ @NonNull private Intent mIntent;
+ private int mOriginalIntentFlags;
+ private int mSenderUid;
+ private int mRealSenderUid;
+ private boolean mSticky;
+ private boolean mOrdered;
+ private boolean mResultRequested;
+ private int mSenderProcState;
+ private int mSenderUidState;
+ @Nullable private BroadcastRecord mBroadcastRecord;
+ private int mResult;
+
+ public void setIntent(@NonNull Intent intent) {
+ mIntent = intent;
+ }
+
+ public void setSenderUid(int uid) {
+ mSenderUid = uid;
+ }
+
+ public void setRealSenderUid(int uid) {
+ mRealSenderUid = uid;
+ }
+
+ public void setOriginalIntentFlags(int flags) {
+ mOriginalIntentFlags = flags;
+ }
+
+ public void setSticky(boolean sticky) {
+ mSticky = sticky;
+ }
+
+ public void setOrdered(boolean ordered) {
+ mOrdered = ordered;
+ }
+
+ public void setResultRequested(boolean resultRequested) {
+ mResultRequested = resultRequested;
+ }
+
+ public void setSenderProcState(int procState) {
+ mSenderProcState = procState;
+ }
+
+ public void setSenderUidState(int procState) {
+ mSenderUidState = procState;
+ }
+
+ public void setBroadcastRecord(@NonNull BroadcastRecord record) {
+ mBroadcastRecord = record;
+ }
+
+ public void setResult(int result) {
+ mResult = result;
+ }
+
+ public void logToStatsd() {
+ if (Flags.logBroadcastSentEvent()) {
+ int loggingResult = switch (mResult) {
+ case ActivityManager.BROADCAST_SUCCESS ->
+ BROADCAST_SENT__RESULT__SUCCESS;
+ case ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION ->
+ BROADCAST_SENT__RESULT__FAILED_STICKY_CANT_HAVE_PERMISSION;
+ case ActivityManager.BROADCAST_FAILED_USER_STOPPED ->
+ BROADCAST_SENT__RESULT__FAILED_USER_STOPPED;
+ default -> BROADCAST_SENT__RESULT__UNKNOWN;
+ };
+ int[] types = calculateTypesForLogging();
+ FrameworkStatsLog.write(BROADCAST_SENT, mIntent.getAction(), mIntent.getFlags(),
+ mOriginalIntentFlags, mSenderUid, mRealSenderUid, mIntent.getPackage() != null,
+ mIntent.getComponent() != null,
+ mBroadcastRecord != null ? mBroadcastRecord.receivers.size() : 0,
+ loggingResult,
+ mBroadcastRecord != null ? mBroadcastRecord.getDeliveryGroupPolicy() : 0,
+ ActivityManager.processStateAmToProto(mSenderProcState),
+ ActivityManager.processStateAmToProto(mSenderUidState), types);
+ }
+ }
+
+ private int[] calculateTypesForLogging() {
+ if (mBroadcastRecord != null) {
+ return mBroadcastRecord.calculateTypesForLogging();
+ } else {
+ final IntArray types = new IntArray();
+ if (mSticky) {
+ types.add(BROADCAST_TYPE_STICKY);
+ }
+ if (mOrdered) {
+ types.add(BROADCAST_TYPE_ORDERED);
+ }
+ if (mResultRequested) {
+ types.add(BROADCAST_TYPE_RESULT_TO);
+ }
+ return types.toArray();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index 5315167b46eb..3334393a1618 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -184,3 +184,14 @@ flag {
description: "Defer submitting binder calls to paused processes."
bug: "327038797"
}
+
+flag {
+ name: "log_broadcast_sent_event"
+ namespace: "backstage_power"
+ description: "Log the broadcast send event to Statsd"
+ bug: "355261986"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java b/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java
index f31b2e11b021..2c52e3d8ca67 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java
@@ -241,6 +241,14 @@ public class BiometricFrameworkStatsLogger {
-1 /* sensorId */);
}
+ /** {@see FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED}. */
+ public void reportFingerprintsLoe(int statsModality) {
+ FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
+ statsModality,
+ BiometricsProtoEnums.ISSUE_FINGERPRINTS_LOE,
+ -1 /* sensorId */);
+ }
+
/** {@see FrameworkStatsLog.BIOMETRIC_FRR_NOTIFICATION}. */
public void logFrameworkNotification(int action, int modality) {
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_FRR_NOTIFICATION,
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
index ff1e5d5f91e6..9351bc0811f2 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricLogger.java
@@ -296,6 +296,15 @@ public class BiometricLogger {
mSink.reportUnknownTemplateEnrolledFramework(mStatsModality);
}
+ /** Report unknown enrollment in framework settings */
+ public void logFingerprintsLoe() {
+ if (shouldSkipLogging()) {
+ return;
+ }
+
+ mSink.reportFingerprintsLoe(mStatsModality);
+ }
+
/**
* Get a callback to start/stop ALS capture when the client runs. Do not create
* multiple callbacks since there is at most one light sensor (they will all share
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 77e27ba4df02..7bd905b4524a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
@@ -161,6 +161,11 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide
getLogger().logUnknownEnrollmentInHal();
+ if (mBiometricUtils.hasValidBiometricUserState(getContext(), getTargetUserId())
+ && Flags.notifyFingerprintsLoe()) {
+ getLogger().logFingerprintsLoe();
+ }
+
mCurrentTask.start(mRemoveCallback);
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 9e905abd78ed..55a6ce7142f3 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -64,7 +64,6 @@ import android.app.AppOpsManager;
import android.app.compat.CompatChanges;
import android.companion.virtual.IVirtualDevice;
import android.companion.virtual.VirtualDeviceManager;
-import android.companion.virtual.flags.Flags;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.content.BroadcastReceiver;
@@ -1633,8 +1632,7 @@ public final class DisplayManagerService extends SystemService {
&& (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
// Only a valid media projection or a virtual device can create a mirror virtual
// display.
- if (!canProjectVideo(projection)
- && !isMirroringSupportedByVirtualDevice(virtualDevice)) {
+ if (!canProjectVideo(projection) && virtualDevice == null) {
throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
+ "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
+ "MediaProjection token in order to create a screen sharing virtual "
@@ -1896,10 +1894,6 @@ public final class DisplayManagerService extends SystemService {
return -1;
}
- private static boolean isMirroringSupportedByVirtualDevice(IVirtualDevice virtualDevice) {
- return Flags.interactiveScreenMirror() && virtualDevice != null;
- }
-
private void resizeVirtualDisplayInternal(IBinder appToken,
int width, int height, int densityDpi) {
synchronized (mSyncRoot) {
diff --git a/services/core/java/com/android/server/display/notifications/DisplayNotificationManager.java b/services/core/java/com/android/server/display/notifications/DisplayNotificationManager.java
index 280a7e1e0521..8a8440ba956a 100644
--- a/services/core/java/com/android/server/display/notifications/DisplayNotificationManager.java
+++ b/services/core/java/com/android/server/display/notifications/DisplayNotificationManager.java
@@ -26,6 +26,7 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.res.Resources;
+import android.os.UserHandle;
import android.util.Slog;
import com.android.internal.R;
@@ -197,7 +198,8 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
return;
}
- mNotificationManager.cancel(DISPLAY_NOTIFICATION_TAG, DISPLAY_NOTIFICATION_ID);
+ mNotificationManager.cancelAsUser(DISPLAY_NOTIFICATION_TAG, DISPLAY_NOTIFICATION_ID,
+ UserHandle.CURRENT);
}
/**
@@ -210,8 +212,8 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
return;
}
- mNotificationManager.notify(DISPLAY_NOTIFICATION_TAG, DISPLAY_NOTIFICATION_ID,
- notification);
+ mNotificationManager.notifyAsUser(DISPLAY_NOTIFICATION_TAG, DISPLAY_NOTIFICATION_ID,
+ notification, UserHandle.CURRENT);
}
/**
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 1070f2f8faf1..e1b8e9f559ed 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -1364,14 +1364,14 @@ class MediaRouter2ServiceImpl {
if (manager == null || manager.mLastSessionCreationRequest == null) {
Slog.w(TAG, "requestCreateSessionWithRouter2Locked: "
+ "Ignoring unknown request.");
- userHandler.notifySessionCreationFailedToRouter(routerRecord, requestId);
+ routerRecord.notifySessionCreationFailed(requestId);
return;
}
if (!TextUtils.equals(manager.mLastSessionCreationRequest.mOldSession.getId(),
oldSession.getId())) {
Slog.w(TAG, "requestCreateSessionWithRouter2Locked: "
+ "Ignoring unmatched routing session.");
- userHandler.notifySessionCreationFailedToRouter(routerRecord, requestId);
+ routerRecord.notifySessionCreationFailed(requestId);
return;
}
if (!TextUtils.equals(manager.mLastSessionCreationRequest.mRoute.getId(),
@@ -1384,7 +1384,7 @@ class MediaRouter2ServiceImpl {
} else {
Slog.w(TAG, "requestCreateSessionWithRouter2Locked: "
+ "Ignoring unmatched route.");
- userHandler.notifySessionCreationFailedToRouter(routerRecord, requestId);
+ routerRecord.notifySessionCreationFailed(requestId);
return;
}
}
@@ -1396,7 +1396,7 @@ class MediaRouter2ServiceImpl {
&& !TextUtils.equals(route.getId(), defaultRouteId)) {
Slog.w(TAG, "MODIFY_AUDIO_ROUTING permission is required to transfer to"
+ route);
- userHandler.notifySessionCreationFailedToRouter(routerRecord, requestId);
+ routerRecord.notifySessionCreationFailed(requestId);
return;
}
}
@@ -1484,8 +1484,7 @@ class MediaRouter2ServiceImpl {
&& !TextUtils.equals(route.getId(), defaultRouteId)) {
userHandler.sendMessage(
obtainMessage(
- UserHandler::notifySessionCreationFailedToRouter,
- userHandler,
+ RouterRecord::notifySessionCreationFailed,
routerRecord,
toOriginalRequestId(DUMMY_REQUEST_ID)));
} else {
@@ -1762,12 +1761,7 @@ class MediaRouter2ServiceImpl {
if (routerRecord == null) {
Slog.w(TAG, "requestCreateSessionWithManagerLocked: Ignoring session creation for "
+ "unknown router.");
- try {
- managerRecord.mManager.notifyRequestFailed(requestId, REASON_UNKNOWN_ERROR);
- } catch (RemoteException ex) {
- Slog.w(TAG, "requestCreateSessionWithManagerLocked: Failed to notify failure. "
- + "Manager probably died.");
- }
+ managerRecord.notifyRequestFailed(requestId, REASON_UNKNOWN_ERROR);
return;
}
@@ -1780,10 +1774,8 @@ class MediaRouter2ServiceImpl {
"requestCreateSessionWithManagerLocked: Notifying failure for pending"
+ " session creation request - oldSession: %s, route: %s",
lastRequest.mOldSession, lastRequest.mRoute));
- managerRecord.mUserRecord.mHandler.notifyRequestFailedToManager(
- managerRecord.mManager,
- toOriginalRequestId(lastRequest.mManagerRequestId),
- REASON_UNKNOWN_ERROR);
+ managerRecord.notifyRequestFailed(
+ toOriginalRequestId(lastRequest.mManagerRequestId), REASON_UNKNOWN_ERROR);
}
managerRecord.mLastSessionCreationRequest = new SessionCreationRequest(routerRecord,
MediaRoute2ProviderService.REQUEST_ID_NONE, uniqueRequestId,
@@ -1793,15 +1785,12 @@ class MediaRouter2ServiceImpl {
// As a return, media router will request to create a session.
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(
- UserHandler::requestRouterCreateSessionOnHandler,
- routerRecord.mUserRecord.mHandler,
- uniqueRequestId,
+ RouterRecord::requestCreateSessionByManager,
routerRecord,
managerRecord,
+ uniqueRequestId,
oldSession,
- route,
- transferInitiatorUserHandle,
- transferInitiatorPackageName));
+ route));
}
@GuardedBy("mLock")
@@ -2256,6 +2245,71 @@ class MediaRouter2ServiceImpl {
}
/**
+ * Notifies the corresponding router of a request failure.
+ *
+ * @param requestId The id of the request that failed.
+ */
+ public void notifySessionCreationFailed(int requestId) {
+ try {
+ mRouter.notifySessionCreated(requestId, /* sessionInfo= */ null);
+ } catch (RemoteException ex) {
+ Slog.w(
+ TAG,
+ "Failed to notify router of the session creation failure."
+ + " Router probably died.",
+ ex);
+ }
+ }
+
+ /**
+ * Notifies the corresponding router of the release of the given {@link RoutingSessionInfo}.
+ */
+ public void notifySessionReleased(RoutingSessionInfo sessionInfo) {
+ try {
+ mRouter.notifySessionReleased(sessionInfo);
+ } catch (RemoteException ex) {
+ Slog.w(
+ TAG,
+ "Failed to notify router of the session release. Router probably died.",
+ ex);
+ }
+ }
+
+ /**
+ * Sends the corresponding router a {@link RoutingSessionInfo session} creation request,
+ * with the given {@link MediaRoute2Info} as the initial member.
+ *
+ * <p>Must be called on the thread of the corresponding {@link UserHandler}.
+ *
+ * @param managerRecord The record of the manager that made the request.
+ * @param uniqueRequestId The id of the request.
+ * @param oldSession The session from which the transfer originated.
+ * @param route The initial route member of the session to create.
+ */
+ public void requestCreateSessionByManager(
+ ManagerRecord managerRecord,
+ long uniqueRequestId,
+ RoutingSessionInfo oldSession,
+ MediaRoute2Info route) {
+ try {
+ if (route.isSystemRoute() && !hasSystemRoutingPermission()) {
+ // The router lacks permission to modify system routing, so we hide system
+ // route info from them.
+ route = mUserRecord.mHandler.mSystemProvider.getDefaultRoute();
+ }
+ mRouter.requestCreateSessionByManager(uniqueRequestId, oldSession, route);
+ } catch (RemoteException ex) {
+ Slog.w(
+ TAG,
+ "getSessionHintsForCreatingSessionOnHandler: "
+ + "Failed to request. Router probably died.",
+ ex);
+ managerRecord.notifyRequestFailed(
+ toOriginalRequestId(uniqueRequestId), REASON_UNKNOWN_ERROR);
+ }
+ }
+
+ /**
* Sends the corresponding router an update for the given session.
*
* <p>Note: These updates are not directly visible to the app.
@@ -2360,6 +2414,25 @@ class MediaRouter2ServiceImpl {
}
}
+ /**
+ * Notifies the corresponding manager of a request failure.
+ *
+ * <p>Must be called on the thread of the corresponding {@link UserHandler}.
+ *
+ * @param requestId The id of the request that failed.
+ * @param reason The reason of the failure. One of
+ */
+ public void notifyRequestFailed(int requestId, int reason) {
+ try {
+ mManager.notifyRequestFailed(requestId, reason);
+ } catch (RemoteException ex) {
+ Slog.w(
+ TAG,
+ "Failed to notify manager of the request failure. Manager probably died.",
+ ex);
+ }
+ }
+
private void updateScanningState(@ScanningState int scanningState) {
if (mScanningState == scanningState) {
return;
@@ -2738,30 +2811,6 @@ class MediaRouter2ServiceImpl {
return -1;
}
- private void requestRouterCreateSessionOnHandler(
- long uniqueRequestId,
- @NonNull RouterRecord routerRecord,
- @NonNull ManagerRecord managerRecord,
- @NonNull RoutingSessionInfo oldSession,
- @NonNull MediaRoute2Info route,
- @NonNull UserHandle transferInitiatorUserHandle,
- @NonNull String transferInitiatorPackageName) {
- try {
- if (route.isSystemRoute() && !routerRecord.hasSystemRoutingPermission()) {
- // The router lacks permission to modify system routing, so we hide system
- // route info from them.
- route = mSystemProvider.getDefaultRoute();
- }
- routerRecord.mRouter.requestCreateSessionByManager(
- uniqueRequestId, oldSession, route);
- } catch (RemoteException ex) {
- Slog.w(TAG, "getSessionHintsForCreatingSessionOnHandler: "
- + "Failed to request. Router probably died.", ex);
- notifyRequestFailedToManager(managerRecord.mManager,
- toOriginalRequestId(uniqueRequestId), REASON_UNKNOWN_ERROR);
- }
- }
-
private void requestCreateSessionWithRouter2OnHandler(
long uniqueRequestId,
long managerRequestId,
@@ -2774,8 +2823,7 @@ class MediaRouter2ServiceImpl {
if (provider == null) {
Slog.w(TAG, "requestCreateSessionWithRouter2OnHandler: Ignoring session "
+ "creation request since no provider found for given route=" + route);
- notifySessionCreationFailedToRouter(routerRecord,
- toOriginalRequestId(uniqueRequestId));
+ routerRecord.notifySessionCreationFailed(toOriginalRequestId(uniqueRequestId));
return;
}
@@ -3054,7 +3102,7 @@ class MediaRouter2ServiceImpl {
+ sessionInfo);
return;
}
- notifySessionReleasedToRouter(routerRecord, sessionInfo);
+ routerRecord.notifySessionReleased(sessionInfo);
}
private void onRequestFailedOnHandler(@NonNull MediaRoute2Provider provider,
@@ -3073,8 +3121,7 @@ class MediaRouter2ServiceImpl {
final int requesterId = toRequesterId(uniqueRequestId);
ManagerRecord manager = findManagerWithId(requesterId);
if (manager != null) {
- notifyRequestFailedToManager(
- manager.mManager, toOriginalRequestId(uniqueRequestId), reason);
+ manager.notifyRequestFailed(toOriginalRequestId(uniqueRequestId), reason);
}
// Currently, only manager records can get notified of failures.
@@ -3109,40 +3156,19 @@ class MediaRouter2ServiceImpl {
// Notify the requester about the failure.
// The call should be made by either MediaRouter2 or MediaRouter2Manager.
if (matchingRequest.mManagerRequestId == MediaRouter2Manager.REQUEST_ID_NONE) {
- notifySessionCreationFailedToRouter(
- matchingRequest.mRouterRecord, toOriginalRequestId(uniqueRequestId));
+ matchingRequest.mRouterRecord.notifySessionCreationFailed(
+ toOriginalRequestId(uniqueRequestId));
} else {
final int requesterId = toRequesterId(matchingRequest.mManagerRequestId);
ManagerRecord manager = findManagerWithId(requesterId);
if (manager != null) {
- notifyRequestFailedToManager(manager.mManager,
+ manager.notifyRequestFailed(
toOriginalRequestId(matchingRequest.mManagerRequestId), reason);
}
}
return true;
}
- private void notifySessionCreationFailedToRouter(@NonNull RouterRecord routerRecord,
- int requestId) {
- try {
- routerRecord.mRouter.notifySessionCreated(requestId,
- /* sessionInfo= */ null);
- } catch (RemoteException ex) {
- Slog.w(TAG, "Failed to notify router of the session creation failure."
- + " Router probably died.", ex);
- }
- }
-
- private void notifySessionReleasedToRouter(@NonNull RouterRecord routerRecord,
- @NonNull RoutingSessionInfo sessionInfo) {
- try {
- routerRecord.mRouter.notifySessionReleased(sessionInfo);
- } catch (RemoteException ex) {
- Slog.w(TAG, "Failed to notify router of the session release."
- + " Router probably died.", ex);
- }
- }
-
private List<IMediaRouter2Manager> getManagers() {
final List<IMediaRouter2Manager> managers = new ArrayList<>();
MediaRouter2ServiceImpl service = mServiceRef.get();
@@ -3379,16 +3405,6 @@ class MediaRouter2ServiceImpl {
// need to update routers other than the one making the update.
}
- private void notifyRequestFailedToManager(@NonNull IMediaRouter2Manager manager,
- int requestId, int reason) {
- try {
- manager.notifyRequestFailed(requestId, reason);
- } catch (RemoteException ex) {
- Slog.w(TAG, "Failed to notify manager of the request failure."
- + " Manager probably died.", ex);
- }
- }
-
private void updateDiscoveryPreferenceOnHandler() {
MediaRouter2ServiceImpl service = mServiceRef.get();
if (service == null) {
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 1cdab44a5b1b..008746c0423c 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -118,11 +118,32 @@ public class GroupHelper {
private final ArrayMap<FullyQualifiedGroupKey, ArrayMap<String, NotificationAttributes>>
mAggregatedNotifications = new ArrayMap<>();
- private static final List<NotificationSectioner> NOTIFICATION_SHADE_SECTIONS = List.of(
- new NotificationSectioner("AlertingSection", 0, (record) ->
- record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT),
- new NotificationSectioner("SilentSection", 1, (record) ->
- record.getImportance() < NotificationManager.IMPORTANCE_DEFAULT));
+ private static List<NotificationSectioner> NOTIFICATION_SHADE_SECTIONS =
+ getNotificationShadeSections();
+
+ private static List<NotificationSectioner> getNotificationShadeSections() {
+ if (android.service.notification.Flags.notificationClassification()) {
+ return List.of(
+ new NotificationSectioner("PromotionsSection", 0, (record) ->
+ NotificationChannel.PROMOTIONS_ID.equals(record.getChannel().getId())),
+ new NotificationSectioner("SocialSection", 0, (record) ->
+ NotificationChannel.SOCIAL_MEDIA_ID.equals(record.getChannel().getId())),
+ new NotificationSectioner("NewsSection", 0, (record) ->
+ NotificationChannel.NEWS_ID.equals(record.getChannel().getId())),
+ new NotificationSectioner("RecsSection", 0, (record) ->
+ NotificationChannel.RECS_ID.equals(record.getChannel().getId())),
+ new NotificationSectioner("AlertingSection", 0, (record) ->
+ record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT),
+ new NotificationSectioner("SilentSection", 1, (record) ->
+ record.getImportance() < NotificationManager.IMPORTANCE_DEFAULT));
+ } else {
+ return List.of(
+ new NotificationSectioner("AlertingSection", 0, (record) ->
+ record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT),
+ new NotificationSectioner("SilentSection", 1, (record) ->
+ record.getImportance() < NotificationManager.IMPORTANCE_DEFAULT));
+ }
+ }
public GroupHelper(Context context, PackageManager packageManager, int autoGroupAtCount,
int autoGroupSparseGroupsAtCount, Callback callback) {
@@ -131,6 +152,7 @@ public class GroupHelper {
mContext = context;
mPackageManager = packageManager;
mAutogroupSparseGroupsAtCount = autoGroupSparseGroupsAtCount;
+ NOTIFICATION_SHADE_SECTIONS = getNotificationShadeSections();
}
private String generatePackageKey(int userId, String pkg) {
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index aaa38a3a1331..6c78b3c85e18 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -887,7 +887,7 @@ final class DefaultPermissionGrantPolicy {
grantPermissionsToSystemPackage(pm,
getDefaultSystemHandlerActivityPackage(pm,
SearchManager.INTENT_ACTION_GLOBAL_SEARCH, userId),
- userId, PHONE_PERMISSIONS, CALENDAR_PERMISSIONS);
+ userId, PHONE_PERMISSIONS, CALENDAR_PERMISSIONS, NEARBY_DEVICES_PERMISSIONS);
}
// Print Spooler
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 4f28e023da92..e91097cbd8f8 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -16,6 +16,8 @@
package com.android.server.rollback;
+import static android.content.pm.Flags.provideInfoOfApkInApex;
+
import android.annotation.AnyThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -23,6 +25,7 @@ import android.annotation.WorkerThread;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.content.rollback.PackageRollbackInfo;
@@ -230,7 +233,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
@Override
- public String getName() {
+ public String getUniqueIdentifier() {
return NAME;
}
@@ -486,19 +489,40 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
*/
@AnyThread
private boolean isModule(String packageName) {
- // Check if the package is an APK inside an APEX. If it is, use the parent APEX package when
- // querying PackageManager.
- String apexPackageName = mApexManager.getActiveApexPackageNameContainingPackage(
- packageName);
- if (apexPackageName != null) {
- packageName = apexPackageName;
- }
-
PackageManager pm = mContext.getPackageManager();
- try {
- return pm.getModuleInfo(packageName, 0) != null;
- } catch (PackageManager.NameNotFoundException ignore) {
- return false;
+
+ if (Flags.refactorCrashrecovery() && provideInfoOfApkInApex()) {
+ // Check if the package is listed among the system modules.
+ boolean isApex = false;
+ try {
+ isApex = (pm.getModuleInfo(packageName, 0 /* flags */) != null);
+ } catch (PackageManager.NameNotFoundException e) {
+ //pass
+ }
+
+ // Check if the package is an APK inside an APEX.
+ boolean isApkInApex = false;
+ try {
+ final PackageInfo pkg = pm.getPackageInfo(packageName, 0 /* flags */);
+ isApkInApex = (pkg.getApexPackageName() != null);
+ } catch (PackageManager.NameNotFoundException e) {
+ // pass
+ }
+ return isApex || isApkInApex;
+ } else {
+ // Check if the package is an APK inside an APEX. If it is, use the parent APEX package
+ // when querying PackageManager.
+ String apexPackageName = mApexManager.getActiveApexPackageNameContainingPackage(
+ packageName);
+ if (apexPackageName != null) {
+ packageName = apexPackageName;
+ }
+
+ try {
+ return pm.getModuleInfo(packageName, 0) != null;
+ } catch (PackageManager.NameNotFoundException ignore) {
+ return false;
+ }
}
}
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index f2ad5b95fe5e..dd16d2433a64 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -487,25 +487,37 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
HalVibration performHapticFeedbackInternal(
int uid, int deviceId, String opPkg, int constant, String reason,
IBinder token, int flags, int privFlags) {
+
+ // Make sure we report the constant id in the requested haptic feedback reason.
+ reason = "performHapticFeedback(constant=" + constant + "): " + reason;
+
HapticFeedbackVibrationProvider hapticVibrationProvider = getHapticVibrationProvider();
if (hapticVibrationProvider == null) {
Slog.e(TAG, "performHapticFeedback; haptic vibration provider not ready.");
+ logAndRecordPerformHapticFeedbackAttempt(uid, deviceId, opPkg, reason,
+ Vibration.Status.IGNORED_ERROR_SCHEDULING);
return null;
}
+
if (hapticVibrationProvider.isRestrictedHapticFeedback(constant)
&& !hasPermission(android.Manifest.permission.VIBRATE_SYSTEM_CONSTANTS)) {
Slog.w(TAG, "performHapticFeedback; no permission for system constant " + constant);
+ logAndRecordPerformHapticFeedbackAttempt(uid, deviceId, opPkg, reason,
+ Vibration.Status.IGNORED_MISSING_PERMISSION);
return null;
}
+
VibrationEffect effect = hapticVibrationProvider.getVibrationForHapticFeedback(constant);
if (effect == null) {
Slog.w(TAG, "performHapticFeedback; vibration absent for constant " + constant);
+ logAndRecordPerformHapticFeedbackAttempt(uid, deviceId, opPkg, reason,
+ Vibration.Status.IGNORED_UNSUPPORTED);
return null;
}
+
CombinedVibration vib = CombinedVibration.createParallel(effect);
VibrationAttributes attrs = hapticVibrationProvider.getVibrationAttributesForHapticFeedback(
constant, flags, privFlags);
- reason = "performHapticFeedback(constant=" + constant + "): " + reason;
VibratorFrameworkStatsLogger.logPerformHapticsFeedbackIfKeyboard(uid, constant);
return vibrateWithoutPermissionCheck(uid, deviceId, opPkg, vib, attrs, reason, token);
}
@@ -563,22 +575,27 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
private HalVibration vibrateInternal(int uid, int deviceId, String opPkg,
@NonNull CombinedVibration effect, @NonNull VibrationAttributes attrs,
String reason, IBinder token) {
+ Vibration.CallerInfo callerInfo =
+ new Vibration.CallerInfo(attrs, uid, deviceId, opPkg, reason);
if (token == null) {
Slog.e(TAG, "token must not be null");
+ logAndRecordVibrationAttempt(effect, callerInfo, Vibration.Status.IGNORED_ERROR_TOKEN);
return null;
}
if (effect.hasVendorEffects()
&& !hasPermission(android.Manifest.permission.VIBRATE_VENDOR_EFFECTS)) {
- Slog.w(TAG, "vibrate; no permission for vendor effects");
+ Slog.e(TAG, "vibrate; no permission for vendor effects");
+ logAndRecordVibrationAttempt(effect, callerInfo,
+ Vibration.Status.IGNORED_MISSING_PERMISSION);
return null;
}
enforceUpdateAppOpsStatsPermission(uid);
if (!isEffectValid(effect)) {
+ logAndRecordVibrationAttempt(effect, callerInfo, Vibration.Status.IGNORED_UNSUPPORTED);
return null;
}
// Create Vibration.Stats as close to the received request as possible, for tracking.
- HalVibration vib = new HalVibration(token, effect,
- new Vibration.CallerInfo(attrs, uid, deviceId, opPkg, reason));
+ HalVibration vib = new HalVibration(token, effect, callerInfo);
fillVibrationFallbacks(vib, effect);
if (attrs.isFlagSet(VibrationAttributes.FLAG_INVALIDATE_SETTINGS_CACHE)) {
@@ -973,6 +990,22 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
return new Vibration.EndInfo(Vibration.Status.FORWARDED_TO_INPUT_DEVICES);
}
+ private void logAndRecordPerformHapticFeedbackAttempt(int uid, int deviceId, String opPkg,
+ String reason, Vibration.Status status) {
+ Vibration.CallerInfo callerInfo = new Vibration.CallerInfo(
+ VibrationAttributes.createForUsage(VibrationAttributes.USAGE_UNKNOWN),
+ uid, deviceId, opPkg, reason);
+ logAndRecordVibrationAttempt(/* effect= */ null, callerInfo, status);
+ }
+
+ private void logAndRecordVibrationAttempt(@Nullable CombinedVibration effect,
+ Vibration.CallerInfo callerInfo, Vibration.Status status) {
+ logAndRecordVibration(
+ new Vibration.DebugInfo(status, new VibrationStats(),
+ effect, /* originalEffect= */ null, VibrationScaler.SCALE_NONE,
+ VibrationScaler.ADAPTIVE_SCALE_NONE, callerInfo));
+ }
+
private void logAndRecordVibration(Vibration.DebugInfo info) {
info.logMetrics(mFrameworkStatsLogger);
logVibrationStatus(info.mCallerInfo.uid, info.mCallerInfo.attrs, info.mStatus);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 3d5808210e00..5e030661c668 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -4626,7 +4626,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return kept;
}
- /** Update default (global) configuration and notify listeners about changes. */
+ /**
+ * Updates default (global) configuration and notifies listeners about changes.
+ *
+ * @param values The new configuration. It must always be a new instance from the caller, and
+ * it won't be modified after calling this method.
+ */
int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
boolean persistent, int userId) {
@@ -4640,24 +4645,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
ProtoLog.i(WM_DEBUG_CONFIGURATION, "Updating global configuration "
+ "to: %s", values);
writeConfigurationChanged(changes);
- FrameworkStatsLog.write(FrameworkStatsLog.RESOURCE_CONFIGURATION_CHANGED,
- values.colorMode,
- values.densityDpi,
- values.fontScale,
- values.hardKeyboardHidden,
- values.keyboard,
- values.keyboardHidden,
- values.mcc,
- values.mnc,
- values.navigation,
- values.navigationHidden,
- values.orientation,
- values.screenHeightDp,
- values.screenLayout,
- values.screenWidthDp,
- values.smallestScreenWidthDp,
- values.touchscreen,
- values.uiMode);
// Note: certain tests currently run as platform_app which is not allowed
// to set debug system properties. To ensure that system properties are set
@@ -4705,13 +4692,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// resources have that config before following boot code is executed.
mSystemThread.applyConfigurationToResources(mTempConfig);
- if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
- final Message msg = PooledLambda.obtainMessage(
- ActivityTaskManagerService::sendPutConfigurationForUserMsg,
- this, userId, new Configuration(mTempConfig));
- mH.sendMessage(msg);
- }
-
SparseArray<WindowProcessController> pidMap = mProcessMap.getPidMap();
for (int i = pidMap.size() - 1; i >= 0; i--) {
final int pid = pidMap.keyAt(i);
@@ -4721,19 +4701,32 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
app.onConfigurationChanged(mTempConfig);
}
- final Message msg = PooledLambda.obtainMessage(
- ActivityManagerInternal::broadcastGlobalConfigurationChanged,
- mAmInternal, changes, initLocale);
- mH.sendMessage(msg);
+ final Configuration configurationForSettings =
+ persistent && Settings.System.hasInterestingConfigurationChanges(changes)
+ ? new Configuration(mTempConfig) : null;
+ mH.post(() -> {
+ FrameworkStatsLog.write(FrameworkStatsLog.RESOURCE_CONFIGURATION_CHANGED,
+ values.colorMode, values.densityDpi, values.fontScale,
+ values.hardKeyboardHidden, values.keyboard, values.keyboardHidden,
+ values.mcc, values.mnc, values.navigation, values.navigationHidden,
+ values.orientation, values.screenHeightDp, values.screenLayout,
+ values.screenWidthDp, values.smallestScreenWidthDp, values.touchscreen,
+ values.uiMode);
+ if ((changes & ActivityInfo.CONFIG_ORIENTATION) != 0) {
+ FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_ORIENTATION_CHANGED,
+ values.orientation);
+ }
+ if (configurationForSettings != null) {
+ Settings.System.putConfigurationForUser(mContext.getContentResolver(),
+ configurationForSettings, userId);
+ }
+ mAmInternal.broadcastGlobalConfigurationChanged(changes, initLocale);
+ });
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "RootConfigChange");
// Update stored global config and notify everyone about the change.
mRootWindowContainer.onConfigurationChanged(mTempConfig);
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- if ((changes & ActivityInfo.CONFIG_ORIENTATION) != 0) {
- FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_ORIENTATION_CHANGED,
- values.orientation);
- }
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
return changes;
@@ -4883,11 +4876,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
mWindowManager.setEventDispatching(booted && !mShuttingDown);
}
- private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
- final ContentResolver resolver = mContext.getContentResolver();
- Settings.System.putConfigurationForUser(resolver, config, userId);
- }
-
boolean isActivityStartsLoggingEnabled() {
return mAmInternal.isActivityStartsLoggingEnabled();
}
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 767effd0ef12..87867f6ab7d2 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -283,8 +283,10 @@ class BackNavigationController {
// keyguard locked and activities are unable to show when locked.
backType = BackNavigationInfo.TYPE_CALLBACK;
}
- } else if (currentTask.mAtmService.getLockTaskController().isTaskLocked(currentTask)) {
+ } else if (currentTask.mAtmService.getLockTaskController().isTaskLocked(currentTask)
+ || currentTask.getWindowConfiguration().tasksAreFloating()) {
// Do not predict if current task is in task locked.
+ // Also, it is unable to play cross task animation for floating task.
backType = BackNavigationInfo.TYPE_CALLBACK;
} else {
// Check back-to-home or cross-task
diff --git a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
index 3dba57f8c4cd..37e4449a2dd0 100644
--- a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
+++ b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
@@ -55,10 +55,11 @@ public class DimmerAnimationHelper {
Change() {}
- Change(@NonNull Change other) {
+ void copyFrom(@NonNull Change other) {
mAlpha = other.mAlpha;
mBlurRadius = other.mBlurRadius;
mDimmingContainer = other.mDimmingContainer;
+ mGeometryParent = other.mGeometryParent;
mRelativeLayer = other.mRelativeLayer;
}
@@ -83,8 +84,8 @@ public class DimmerAnimationHelper {
}
}
- private Change mCurrentProperties = new Change();
- private Change mRequestedProperties = new Change();
+ private final Change mCurrentProperties = new Change();
+ private final Change mRequestedProperties = new Change();
private AnimationSpec mAlphaAnimationSpec;
private final AnimationAdapterFactory mAnimationAdapterFactory;
@@ -128,7 +129,7 @@ public class DimmerAnimationHelper {
+ "call adjustRelativeLayer?");
return;
}
- if (mRequestedProperties.mDimmingContainer.mSurfaceControl == null) {
+ if (mRequestedProperties.mDimmingContainer.getSurfaceControl() == null) {
Log.w(TAG, "container " + mRequestedProperties.mDimmingContainer
+ "does not have a surface");
dim.remove(t);
@@ -154,35 +155,35 @@ public class DimmerAnimationHelper {
"%s skipping animation and directly setting alpha=%f, blur=%d",
dim, mRequestedProperties.mAlpha,
mRequestedProperties.mBlurRadius);
- setAlphaBlur(dim.mDimSurface, mRequestedProperties.mAlpha,
- mRequestedProperties.mBlurRadius, t);
+ mCurrentProperties.copyFrom(mRequestedProperties);
+ setCurrentAlphaBlur(dim.mDimSurface, t);
dim.mSkipAnimation = false;
} else {
- startAnimation(t, dim);
+ Change startProperties = mCurrentProperties;
+ mCurrentProperties.copyFrom(mRequestedProperties);
+ startAnimation(t, dim, startProperties, mRequestedProperties);
}
-
} else if (!dim.isDimming()) {
// We are not dimming, so we tried the exit animation but the alpha is already 0,
// therefore, let's just remove this surface
dim.remove(t);
}
- mCurrentProperties = new Change(mRequestedProperties);
}
private void startAnimation(
- @NonNull SurfaceControl.Transaction t, @NonNull Dimmer.DimState dim) {
+ @NonNull SurfaceControl.Transaction t, @NonNull Dimmer.DimState dim,
+ @NonNull Change from, @NonNull Change to) {
ProtoLog.v(WM_DEBUG_DIMMER, "Starting animation on %s", dim);
- mAlphaAnimationSpec = getRequestedAnimationSpec();
+ mAlphaAnimationSpec = getRequestedAnimationSpec(from, to);
mLocalAnimationAdapter = mAnimationAdapterFactory.get(mAlphaAnimationSpec,
dim.mHostContainer.mWmService.mSurfaceAnimationRunner);
- float targetAlpha = mRequestedProperties.mAlpha;
- int targetBlur = mRequestedProperties.mBlurRadius;
+ float targetAlpha = to.mAlpha;
mLocalAnimationAdapter.startAnimation(dim.mDimSurface, t,
ANIMATION_TYPE_DIMMER, /* finishCallback */ (type, animator) -> {
synchronized (dim.mHostContainer.mWmService.mGlobalLock) {
- setAlphaBlur(dim.mDimSurface, targetAlpha, targetBlur, t);
+ setCurrentAlphaBlur(dim.mDimSurface, t);
if (targetAlpha == 0f && !dim.isDimming()) {
dim.remove(t);
}
@@ -207,15 +208,15 @@ public class DimmerAnimationHelper {
}
@NonNull
- private AnimationSpec getRequestedAnimationSpec() {
- final float startAlpha = Math.max(mCurrentProperties.mAlpha, 0f);
- final int startBlur = Math.max(mCurrentProperties.mBlurRadius, 0);
- long duration = (long) (getDimDuration(mRequestedProperties.mDimmingContainer)
- * Math.abs(mRequestedProperties.mAlpha - startAlpha));
+ private static AnimationSpec getRequestedAnimationSpec(Change from, Change to) {
+ final float startAlpha = Math.max(from.mAlpha, 0f);
+ final int startBlur = Math.max(from.mBlurRadius, 0);
+ long duration = (long) (getDimDuration(to.mDimmingContainer)
+ * Math.abs(to.mAlpha - startAlpha));
final AnimationSpec spec = new AnimationSpec(
- new AnimationSpec.AnimationExtremes<>(startAlpha, mRequestedProperties.mAlpha),
- new AnimationSpec.AnimationExtremes<>(startBlur, mRequestedProperties.mBlurRadius),
+ new AnimationSpec.AnimationExtremes<>(startAlpha, to.mAlpha),
+ new AnimationSpec.AnimationExtremes<>(startBlur, to.mBlurRadius),
duration
);
ProtoLog.v(WM_DEBUG_DIMMER, "Dim animation requested: %s", spec);
@@ -225,7 +226,7 @@ public class DimmerAnimationHelper {
/**
* Change the geometry and relative parent of this dim layer
*/
- void reparent(@NonNull SurfaceControl dimLayer,
+ static void reparent(@NonNull SurfaceControl dimLayer,
@Nullable SurfaceControl newGeometryParent,
@NonNull SurfaceControl relativeParent,
int relativePosition,
@@ -240,17 +241,16 @@ public class DimmerAnimationHelper {
}
}
- void setAlphaBlur(@NonNull SurfaceControl sc, float alpha, int blur,
- @NonNull SurfaceControl.Transaction t) {
+ void setCurrentAlphaBlur(@NonNull SurfaceControl sc, @NonNull SurfaceControl.Transaction t) {
try {
- t.setAlpha(sc, alpha);
- t.setBackgroundBlurRadius(sc, blur);
+ t.setAlpha(sc, mCurrentProperties.mAlpha);
+ t.setBackgroundBlurRadius(sc, mCurrentProperties.mBlurRadius);
} catch (NullPointerException e) {
Log.w(TAG , "Tried to change look of dim " + sc + " after remove", e);
}
}
- private long getDimDuration(@NonNull WindowContainer<?> container) {
+ private static long getDimDuration(@NonNull WindowContainer<?> container) {
// Use the same duration as the animation on the WindowContainer
AnimationAdapter animationAdapter = container.mSurfaceAnimator.getAnimation();
final float durationScale = container.mWmService.getTransitionAnimationScaleLocked();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 648f6bda7f98..86285fbc58bb 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3496,10 +3496,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
void collectDisplayChange(@NonNull Transition transition) {
if (!mLastHasContent) return;
- if (!transition.isCollecting()) {
- throw new IllegalArgumentException("Can only collect display change if transition"
- + " is collecting");
- }
+ if (!transition.isCollecting()) return;
if (!transition.mParticipants.contains(this)) {
transition.collect(this);
startAsyncRotationIfNeeded();
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index b528e205eae6..4ca4730923f5 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1002,6 +1002,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// complete configuration.
continue;
}
+ win.updateSurfacePositionIfNeeded();
win.reportResized();
mWmService.mResizingWindows.remove(i);
}
@@ -3427,26 +3428,30 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
boolean allResumedActivitiesIdle() {
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
- // TODO(b/117135575): Check resumed activities on all visible root tasks.
final DisplayContent display = getChildAt(displayNdx);
if (display.isSleeping()) {
// No resumed activities while display is sleeping.
continue;
}
- // If the focused root task is not null or not empty, there should have some activities
- // resuming or resumed. Make sure these activities are idle.
- final Task rootTask = display.getFocusedRootTask();
- if (rootTask == null || !rootTask.hasActivity()) {
- continue;
- }
- final ActivityRecord resumedActivity = rootTask.getTopResumedActivity();
- if (resumedActivity == null || !resumedActivity.idle) {
- ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: rootTask=%d %s "
- + "not idle", rootTask.getRootTaskId(), resumedActivity);
+ final boolean foundNotIdle = display.forAllLeafTaskFragments(tf -> {
+ if (!tf.isVisibleRequested()) {
+ return false;
+ }
+ // Note that only activities that will be resumed can report idle.
+ final ActivityRecord r = tf.topRunningActivity();
+ if (r != null && !r.idle && (r.isState(RESUMED)
+ // Its process is not attached yet and it may resume later.
+ || (r.app == null && r.isFocusable()))) {
+ ProtoLog.d(WM_DEBUG_STATES, "allResumedActivitiesIdle: %s not idle", r);
+ return true;
+ }
+ return false;
+ });
+ if (foundNotIdle) {
return false;
}
- if (mTransitionController.isTransientLaunch(resumedActivity)) {
+ if (mTransitionController.hasTransientLaunch(display)) {
// Not idle if the transient transition animation is running.
return false;
}
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index ef25eda1d876..1d2b693995c8 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -408,6 +408,10 @@ class TransitionController {
*/
@Nullable
Transition getCollectingTransition() {
+ if (mCollectingTransition != null && !mCollectingTransition.isCollecting()) {
+ Slog.wtfStack(TAG, "Collecting Transition (#" + mCollectingTransition.getSyncId()
+ + ") is not collecting. state=" + mCollectingTransition.getState());
+ }
return mCollectingTransition;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index bdb1d43faf79..87c0084083be 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -32,6 +32,7 @@ import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.StatusBarManager.DISABLE_MASK;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
import static android.content.pm.PackageManager.FEATURE_PC;
@@ -9024,14 +9025,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
clearPointerDownOutsideFocusRunnable();
- // For embedded activity that is showing side-by-side with another activity, delay
- // handling the touch-outside event to prevent focus rapid changes back-n-forth.
- // Otherwise, handle the touch-outside event directly.
- final WindowState w = t.getWindowState();
- final ActivityRecord activity = w != null ? w.getActivityRecord() : null;
- if (mFocusedInputTarget != t && mFocusedInputTarget != null
- && activity != null && activity.isEmbedded()
- && activity.getTaskFragment().getAdjacentTaskFragment() != null) {
+ if (shouldDelayTouchOutside(t)) {
mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
mH.postDelayed(mPointerDownOutsideFocusRunnable, POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS);
} else if (!fromHandler) {
@@ -9044,6 +9038,33 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ private boolean shouldDelayTouchOutside(InputTarget t) {
+ final WindowState w = t.getWindowState();
+ final ActivityRecord activity = w != null ? w.getActivityRecord() : null;
+ final Task task = w != null ? w.getRootTask() : null;
+
+ final boolean isInputTargetNotFocused =
+ mFocusedInputTarget != t && mFocusedInputTarget != null;
+ if (!isInputTargetNotFocused) {
+ return false;
+ }
+
+ // For embedded activity that is showing side-by-side with another activity, delay
+ // handling the touch-outside event to prevent focus rapid changes back-n-forth.
+ final boolean shouldDelayTouchForEmbeddedActivity = activity != null
+ && activity.isEmbedded()
+ && activity.getTaskFragment().getAdjacentTaskFragment() != null;
+
+ // For cases when there are multiple freeform windows where non-top windows are blocking
+ // the gesture zones, delay handling the touch-outside event to prevent refocusing the
+ // the non-top windows during the gesture.
+ final boolean shouldDelayTouchForFreeform =
+ task != null && task.getWindowingMode() == WINDOWING_MODE_FREEFORM;
+
+ // If non of the above cases are true, handle the touch-outside event directly.
+ return shouldDelayTouchForEmbeddedActivity || shouldDelayTouchForFreeform;
+ }
+
private void handlePointerDownOutsideFocus(InputTarget t) {
synchronized (mGlobalLock) {
if (mPointerDownOutsideFocusRunnable != null
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 923ad4bb51bb..4568f2eac95c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -5333,6 +5333,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
super.prepareSurfaces();
}
+ void updateSurfacePositionIfNeeded() {
+ if (mWindowFrames.mRelFrame.top == mWindowFrames.mLastRelFrame.top
+ && mWindowFrames.mRelFrame.left == mWindowFrames.mLastRelFrame.left) {
+ return;
+ }
+ updateSurfacePosition(getSyncTransaction());
+ }
+
@Override
@VisibleForTesting
void updateSurfacePosition(Transaction t) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index 2b03dc4f78ad..bbf2ecbb9380 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -69,7 +69,6 @@ import android.app.PropertyInvalidatedCache;
import android.companion.virtual.IVirtualDevice;
import android.companion.virtual.IVirtualDeviceManager;
import android.companion.virtual.VirtualDeviceManager;
-import android.companion.virtual.flags.Flags;
import android.compat.testing.PlatformCompatChangeRule;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -374,7 +373,6 @@ public class DisplayManagerServiceTest {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mMockFlags.isConnectedDisplayManagementEnabled()).thenReturn(false);
- mSetFlagsRule.disableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR);
mLocalServiceKeeperRule.overrideLocalService(
InputManagerInternal.class, mMockInputManagerInternal);
@@ -1298,44 +1296,11 @@ public class DisplayManagerServiceTest {
}
/**
- * Tests that it's not allowed to create an auto-mirror virtual display when display mirroring
- * is not supported in a virtual device.
- */
- @Test
- public void createAutoMirrorDisplay_virtualDeviceDoesntSupportMirroring_throwsException()
- throws Exception {
- mSetFlagsRule.disableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR);
- DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
- DisplayManagerInternal localService = displayManager.new LocalService();
- registerDefaultDisplays(displayManager);
- when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
- when(mContext.checkCallingPermission(CAPTURE_VIDEO_OUTPUT)).thenReturn(
- PackageManager.PERMISSION_DENIED);
- IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
- when(virtualDevice.getDeviceId()).thenReturn(1);
- when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
-
- final VirtualDisplayConfig.Builder builder =
- new VirtualDisplayConfig.Builder(VIRTUAL_DISPLAY_NAME, 600, 800, 320)
- .setFlags(VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR)
- .setUniqueId("uniqueId --- mirror display");
- assertThrows(SecurityException.class, () -> {
- localService.createVirtualDisplay(
- builder.build(),
- mMockAppToken /* callback */,
- virtualDevice /* virtualDeviceToken */,
- mock(DisplayWindowPolicyController.class),
- PACKAGE_NAME);
- });
- }
-
- /**
* Tests that the virtual display is added to the default display group when created with
* VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR using a virtual device.
*/
@Test
public void createAutoMirrorVirtualDisplay_addsDisplayToDefaultDisplayGroup() throws Exception {
- mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR);
DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
DisplayManagerInternal localService = displayManager.new LocalService();
registerDefaultDisplays(displayManager);
@@ -1368,7 +1333,6 @@ public class DisplayManagerServiceTest {
*/
@Test
public void createAutoMirrorVirtualDisplay_mirrorsDefaultDisplay() throws Exception {
- mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR);
DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
DisplayManagerInternal localService = displayManager.new LocalService();
registerDefaultDisplays(displayManager);
@@ -1400,7 +1364,6 @@ public class DisplayManagerServiceTest {
*/
@Test
public void createOwnContentOnlyVirtualDisplay_doesNotMirrorAnyDisplay() throws Exception {
- mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR);
DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
DisplayManagerInternal localService = displayManager.new LocalService();
registerDefaultDisplays(displayManager);
@@ -1436,7 +1399,6 @@ public class DisplayManagerServiceTest {
*/
@Test
public void createAutoMirrorVirtualDisplay_flagAlwaysUnlockedNotSet() throws Exception {
- mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR);
DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
DisplayManagerInternal localService = displayManager.new LocalService();
registerDefaultDisplays(displayManager);
@@ -1472,7 +1434,6 @@ public class DisplayManagerServiceTest {
*/
@Test
public void createAutoMirrorVirtualDisplay_flagPresentationNotSet() throws Exception {
- mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR);
DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
DisplayManagerInternal localService = displayManager.new LocalService();
registerDefaultDisplays(displayManager);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/notifications/DisplayNotificationManagerTest.java b/services/tests/displayservicetests/src/com/android/server/display/notifications/DisplayNotificationManagerTest.java
index d6c8ceb7ea6f..97c12bb6ef33 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/notifications/DisplayNotificationManagerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/notifications/DisplayNotificationManagerTest.java
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.NotificationManager;
+import android.os.UserHandle;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
@@ -70,6 +71,8 @@ public class DisplayNotificationManagerTest {
private ArgumentCaptor<Integer> mNotifyNoteIdCaptor;
@Captor
private ArgumentCaptor<Notification> mNotifyAsUserNotificationCaptor;
+ @Captor
+ private ArgumentCaptor<UserHandle> mNotifyAsUserCaptor;
/** Setup tests. */
@Before
@@ -127,7 +130,8 @@ public class DisplayNotificationManagerTest {
dnm.onDisplayPortLinkTrainingFailure();
dnm.onCableNotCapableDisplayPort();
dnm.onHighTemperatureExternalDisplayNotAllowed();
- verify(mMockedNotificationManager, never()).notify(anyString(), anyInt(), any());
+ verify(mMockedNotificationManager, never()).notifyAsUser(anyString(), anyInt(), any(),
+ any());
}
@Test
@@ -175,10 +179,11 @@ public class DisplayNotificationManagerTest {
}
private void assertExpectedNotification() {
- verify(mMockedNotificationManager).notify(
+ verify(mMockedNotificationManager).notifyAsUser(
mNotifyTagCaptor.capture(),
mNotifyNoteIdCaptor.capture(),
- mNotifyAsUserNotificationCaptor.capture());
+ mNotifyAsUserNotificationCaptor.capture(),
+ mNotifyAsUserCaptor.capture());
assertThat(mNotifyTagCaptor.getValue()).isEqualTo("DisplayNotificationManager");
assertThat((int) mNotifyNoteIdCaptor.getValue()).isEqualTo(1);
final var notification = mNotifyAsUserNotificationCaptor.getValue();
@@ -188,5 +193,7 @@ public class DisplayNotificationManagerTest {
assertThat(notification.flags & FLAG_ONGOING_EVENT).isEqualTo(0);
assertThat(notification.when).isEqualTo(0);
assertThat(notification.getTimeoutAfter()).isEqualTo(30000L);
+ final var user = mNotifyAsUserCaptor.getValue();
+ assertThat(user).isEqualTo(UserHandle.CURRENT);
}
}
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
index b4e1abff3bf7..265b74dcee22 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -215,4 +216,39 @@ public class DreamServiceTest {
// Ensure service does not crash from only receiving up event.
environment.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_SPACE));
}
+
+ @Test
+ @EnableFlags(Flags.FLAG_DREAM_HANDLES_BEING_OBSCURED)
+ public void testComeToFront() throws Exception {
+ TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+ .setDreamOverlayPresent(true)
+ .build();
+ environment.advance(TestDreamEnvironment.DREAM_STATE_STARTED);
+
+ // Call comeToFront through binder.
+ environment.resetClientInvocations();
+ environment.comeToFront();
+ mTestableLooper.processAllMessages();
+
+ // Overlay client receives call.
+ verify(environment.getDreamOverlayClient()).comeToFront();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_DREAM_HANDLES_BEING_OBSCURED)
+ public void testComeToFront_noOverlay() throws Exception {
+ // Dream environment with no overlay present
+ TestDreamEnvironment environment = new TestDreamEnvironment.Builder(mTestableLooper)
+ .setDreamOverlayPresent(false)
+ .build();
+ environment.advance(TestDreamEnvironment.DREAM_STATE_STARTED);
+
+ // Call comeToFront through binder.
+ environment.resetClientInvocations();
+ environment.comeToFront();
+ mTestableLooper.processAllMessages();
+
+ // Overlay client receives call.
+ verify(environment.getDreamOverlayClient(), never()).comeToFront();
+ }
}
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java
index e2b93ae3e9e7..43aa7fe46ca5 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java
@@ -398,10 +398,14 @@ public class TestDreamEnvironment {
mService.dispatchKeyEvent(event);
}
- private void wakeDream() throws RemoteException {
+ private void wakeDream() {
mService.wakeUp();
}
+ void comeToFront() throws RemoteException {
+ mDreamServiceWrapper.comeToFront();
+ }
+
/**
* Retrieves the dream overlay callback.
*/
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java
index 238a9289c05b..8f23ab99ba7f 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricLoggerTest.java
@@ -236,6 +236,13 @@ public class BiometricLoggerTest {
}
@Test
+ public void testFingerprintsLoe() {
+ mLogger = createLogger();
+ mLogger.logFingerprintsLoe();
+ verify(mSink).reportFingerprintsLoe(eq(DEFAULT_MODALITY));
+ }
+
+ @Test
public void testALSCallback() {
mLogger = createLogger();
final CallbackWithProbe<Probe> callback =
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClientTest.java
index 242880ca49eb..7dcf8415f311 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClientTest.java
@@ -182,13 +182,22 @@ public class FingerprintInternalCleanupClientTest {
public void invalidBiometricUserState() throws Exception {
mClient = createClient();
+ final List<Fingerprint> templates = List.of(
+ new Fingerprint("one", 1, 1),
+ new Fingerprint("two", 2, 1),
+ new Fingerprint("three", 3, 1)
+ );
+
final List<Fingerprint> list = new ArrayList<>();
doReturn(true).when(mFingerprintUtils)
.hasValidBiometricUserState(mContext, 2);
doReturn(list).when(mFingerprintUtils).getBiometricsForUser(mContext, 2);
mClient.start(mCallback);
- mClient.onEnumerationResult(null, 0);
+ for (int i = templates.size() - 1; i >= 0; i--) {
+ mClient.getCurrentEnumerateClient().onEnumerationResult(templates.get(i), i);
+ }
+ verify(mLogger).logFingerprintsLoe();
verify(mFingerprintUtils).deleteStateForUser(2);
}
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index c2882124e6e3..4d067f6bfc62 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -62,7 +62,6 @@ import android.companion.virtual.VirtualDeviceManager;
import android.companion.virtual.VirtualDeviceParams;
import android.companion.virtual.audio.IAudioConfigChangedCallback;
import android.companion.virtual.audio.IAudioRoutingCallback;
-import android.companion.virtual.flags.Flags;
import android.companion.virtual.sensor.VirtualSensor;
import android.companion.virtual.sensor.VirtualSensorCallback;
import android.companion.virtual.sensor.VirtualSensorConfig;
@@ -1686,7 +1685,6 @@ public class VirtualDeviceManagerServiceTest {
@Test
public void openNonBlockedAppOnMirrorDisplay_flagEnabled_cannotBeLaunched() {
- mSetFlagsRule.enableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR);
when(mDisplayManagerInternalMock.getDisplayIdToMirror(anyInt()))
.thenReturn(Display.DEFAULT_DISPLAY);
addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
@@ -1711,31 +1709,6 @@ public class VirtualDeviceManagerServiceTest {
}
@Test
- public void openNonBlockedAppOnMirrorDisplay_flagDisabled_launchesActivity() {
- mSetFlagsRule.disableFlags(Flags.FLAG_INTERACTIVE_SCREEN_MIRROR);
- when(mDisplayManagerInternalMock.getDisplayIdToMirror(anyInt()))
- .thenReturn(Display.DEFAULT_DISPLAY);
- addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
- GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest(
- DISPLAY_ID_1);
- doNothing().when(mContext).startActivityAsUser(any(), any(), any());
-
- ActivityInfo activityInfo = getActivityInfo(
- NONBLOCKED_APP_PACKAGE_NAME,
- NONBLOCKED_APP_PACKAGE_NAME,
- /* displayOnRemoteDevices */ true,
- /* targetDisplayCategory */ null);
- assertThat(gwpc.canActivityBeLaunched(activityInfo, null,
- WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /* isNewTask= */ false,
- /* isResultExpected = */ false, /* intentSender= */ null))
- .isTrue();
- Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
- activityInfo, mAssociationInfo.getDisplayName());
- verify(mContext, never()).startActivityAsUser(argThat(intent ->
- intent.filterEquals(blockedAppIntent)), any(), any());
- }
-
- @Test
public void registerRunningAppsChangedListener_onRunningAppsChanged_listenersNotified() {
ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(UID_1, UID_2));
addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 225c1dc752c1..51f64ba2b483 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -31,10 +31,11 @@ import static android.app.Notification.VISIBILITY_PUBLIC;
import static android.app.Notification.VISIBILITY_SECRET;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION;
import static android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING;
+import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
-import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
import static com.android.server.notification.GroupHelper.AGGREGATE_GROUP_KEY;
import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY;
import static com.android.server.notification.GroupHelper.BASE_FLAGS;
@@ -2518,17 +2519,7 @@ public class GroupHelperTest extends UiServiceTestCase {
assertThat(cachedSummary).isNull();
}
- @Test
- @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
- public void testGroupSectioners() {
- final NotificationRecord notification_alerting = getNotificationRecord(mPkg, 0, "", mUser,
- "", false, IMPORTANCE_DEFAULT);
- assertThat(GroupHelper.getSection(notification_alerting).mName).isEqualTo("AlertingSection");
-
- final NotificationRecord notification_silent = getNotificationRecord(mPkg, 0, "", mUser,
- "", false, IMPORTANCE_LOW);
- assertThat(GroupHelper.getSection(notification_silent).mName).isEqualTo("SilentSection");
-
+ private void checkNonGroupableNotifications() {
NotificationRecord notification_conversation = mock(NotificationRecord.class);
when(notification_conversation.isConversation()).thenReturn(true);
assertThat(GroupHelper.getSection(notification_conversation)).isNull();
@@ -2545,7 +2536,7 @@ public class GroupHelperTest extends UiServiceTestCase {
assertThat(GroupHelper.getSection(notification_call)).isNull();
NotificationRecord notification_colorFg = spy(getNotificationRecord(mPkg, 0, "", mUser,
- "", false, IMPORTANCE_LOW));
+ "", false, IMPORTANCE_LOW));
sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM));
n = mock(Notification.class);
when(notification_colorFg.isConversation()).thenReturn(false);
@@ -2558,4 +2549,97 @@ public class GroupHelperTest extends UiServiceTestCase {
assertThat(GroupHelper.getSection(notification_colorFg)).isNull();
}
+ @Test
+ @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+ @DisableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
+ public void testGroupSectioners() {
+ final NotificationRecord notification_alerting = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, IMPORTANCE_DEFAULT);
+ assertThat(GroupHelper.getSection(notification_alerting).mName).isEqualTo(
+ "AlertingSection");
+
+ final NotificationRecord notification_silent = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, IMPORTANCE_LOW);
+ assertThat(GroupHelper.getSection(notification_silent).mName).isEqualTo("SilentSection");
+
+ // Check that special categories are grouped by their importance
+ final NotificationChannel promoChannel = new NotificationChannel(
+ NotificationChannel.PROMOTIONS_ID, NotificationChannel.PROMOTIONS_ID,
+ IMPORTANCE_DEFAULT);
+ final NotificationRecord notification_promotion = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, promoChannel);
+ assertThat(GroupHelper.getSection(notification_promotion).mName).isEqualTo(
+ "AlertingSection");
+
+ final NotificationChannel newsChannel = new NotificationChannel(NotificationChannel.NEWS_ID,
+ NotificationChannel.NEWS_ID, IMPORTANCE_DEFAULT);
+ final NotificationRecord notification_news = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, newsChannel);
+ assertThat(GroupHelper.getSection(notification_news).mName).isEqualTo(
+ "AlertingSection");
+
+ final NotificationChannel socialChannel = new NotificationChannel(
+ NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
+ IMPORTANCE_DEFAULT);
+ final NotificationRecord notification_social = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, socialChannel);
+ assertThat(GroupHelper.getSection(notification_social).mName).isEqualTo(
+ "AlertingSection");
+
+ final NotificationChannel recsChannel = new NotificationChannel(NotificationChannel.RECS_ID,
+ NotificationChannel.RECS_ID, IMPORTANCE_DEFAULT);
+ final NotificationRecord notification_recs = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, recsChannel);
+ assertThat(GroupHelper.getSection(notification_recs).mName).isEqualTo(
+ "AlertingSection");
+
+ checkNonGroupableNotifications();
+ }
+
+ @Test
+ @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING, FLAG_NOTIFICATION_CLASSIFICATION})
+ public void testGroupSectioners_withClassificationSections() {
+ final NotificationRecord notification_alerting = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, IMPORTANCE_DEFAULT);
+ assertThat(GroupHelper.getSection(notification_alerting).mName).isEqualTo(
+ "AlertingSection");
+
+ final NotificationRecord notification_silent = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, IMPORTANCE_LOW);
+ assertThat(GroupHelper.getSection(notification_silent).mName).isEqualTo("SilentSection");
+
+ // Check that special categories are grouped in their own sections
+ final NotificationChannel promoChannel = new NotificationChannel(
+ NotificationChannel.PROMOTIONS_ID, NotificationChannel.PROMOTIONS_ID,
+ IMPORTANCE_DEFAULT);
+ final NotificationRecord notification_promotion = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, promoChannel);
+ assertThat(GroupHelper.getSection(notification_promotion).mName).isEqualTo(
+ "PromotionsSection");
+
+ final NotificationChannel newsChannel = new NotificationChannel(NotificationChannel.NEWS_ID,
+ NotificationChannel.NEWS_ID, IMPORTANCE_DEFAULT);
+ final NotificationRecord notification_news = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, newsChannel);
+ assertThat(GroupHelper.getSection(notification_news).mName).isEqualTo(
+ "NewsSection");
+
+ final NotificationChannel socialChannel = new NotificationChannel(
+ NotificationChannel.SOCIAL_MEDIA_ID, NotificationChannel.SOCIAL_MEDIA_ID,
+ IMPORTANCE_DEFAULT);
+ final NotificationRecord notification_social = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, socialChannel);
+ assertThat(GroupHelper.getSection(notification_social).mName).isEqualTo(
+ "SocialSection");
+
+ final NotificationChannel recsChannel = new NotificationChannel(NotificationChannel.RECS_ID,
+ NotificationChannel.RECS_ID, IMPORTANCE_DEFAULT);
+ final NotificationRecord notification_recs = getNotificationRecord(mPkg, 0, "", mUser,
+ "", false, recsChannel);
+ assertThat(GroupHelper.getSection(notification_recs).mName).isEqualTo(
+ "RecsSection");
+
+ checkNonGroupableNotifications();
+ }
+
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 84c2c32054d8..4ab2fcf095d1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -205,6 +205,28 @@ public class RootWindowContainerTests extends WindowTestsBase {
}
@Test
+ public void testAllResumedActivitiesIdle() {
+ final ActivityRecord activity1 = new ActivityBuilder(mAtm).setCreateTask(true).build();
+ final ActivityRecord activity2 = new ActivityBuilder(mAtm).setCreateTask(true).build();
+ final WindowProcessController proc2 = activity2.app;
+ activity1.setState(RESUMED, "test");
+ activity2.detachFromProcess();
+ assertThat(mWm.mRoot.allResumedActivitiesIdle()).isFalse();
+
+ activity1.idle = true;
+ assertThat(mWm.mRoot.allResumedActivitiesIdle()).isFalse();
+
+ activity2.setProcess(proc2);
+ activity2.setState(RESUMED, "test");
+ activity2.idle = true;
+ assertThat(mWm.mRoot.allResumedActivitiesIdle()).isTrue();
+
+ activity1.idle = false;
+ activity1.setVisibleRequested(false);
+ assertThat(mWm.mRoot.allResumedActivitiesIdle()).isTrue();
+ }
+
+ @Test
public void testTaskLayerRank() {
final Task rootTask = new TaskBuilder(mSupervisor).build();
final Task task1 = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index 49e349caa379..56fca31afa37 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -1550,10 +1550,6 @@ public class TransitionTests extends WindowTestsBase {
// An active transient launch overrides idle state to avoid clearing power mode before the
// transition is finished.
- spyOn(mRootWindowContainer.mTransitionController);
- doAnswer(invocation -> controller.isTransientLaunch(invocation.getArgument(0))).when(
- mRootWindowContainer.mTransitionController).isTransientLaunch(any());
- activity2.getTask().setResumedActivity(activity2, "test");
activity2.idle = true;
assertFalse(mRootWindowContainer.allResumedActivitiesIdle());
diff --git a/telephony/java/android/telephony/satellite/SatelliteSubscriberInfo.java b/telephony/java/android/telephony/satellite/SatelliteSubscriberInfo.java
index 50ed6270ccfc..dbe5dddf8ce8 100644
--- a/telephony/java/android/telephony/satellite/SatelliteSubscriberInfo.java
+++ b/telephony/java/android/telephony/satellite/SatelliteSubscriberInfo.java
@@ -268,7 +268,7 @@ public final class SatelliteSubscriberInfo implements Parcelable {
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof SatelliteSubscriberProvisionStatus)) return false;
+ if (!(o instanceof SatelliteSubscriberInfo)) return false;
SatelliteSubscriberInfo that = (SatelliteSubscriberInfo) o;
return Objects.equals(mSubscriberId, that.mSubscriberId) && mCarrierId == that.mCarrierId
&& Objects.equals(mNiddApn, that.mNiddApn) && mSubId == that.mSubId
diff --git a/telephony/java/android/telephony/satellite/SatelliteSubscriberProvisionStatus.java b/telephony/java/android/telephony/satellite/SatelliteSubscriberProvisionStatus.java
index e3d619ea0fc8..08ef3f2d8d12 100644
--- a/telephony/java/android/telephony/satellite/SatelliteSubscriberProvisionStatus.java
+++ b/telephony/java/android/telephony/satellite/SatelliteSubscriberProvisionStatus.java
@@ -90,7 +90,7 @@ public class SatelliteSubscriberProvisionStatus implements Parcelable {
@Override
@FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
public void writeToParcel(@NonNull Parcel out, int flags) {
- mSubscriberInfo.writeToParcel(out, flags);
+ out.writeParcelable(mSubscriberInfo, flags);
out.writeBoolean(mProvisionStatus);
}
diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
index 4b745b289d33..4826f4241e2b 100644
--- a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
@@ -43,7 +43,6 @@ import android.tools.traces.protolog.ProtoLogTrace;
import android.tracing.perfetto.DataSource;
import android.util.proto.ProtoInputStream;
-import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.internal.protolog.common.IProtoLogGroup;
@@ -73,7 +72,6 @@ import java.util.concurrent.atomic.AtomicInteger;
* Test class for {@link ProtoLogImpl}.
*/
@SuppressWarnings("ConstantConditions")
-@SmallTest
@Presubmit
@RunWith(JUnit4.class)
public class PerfettoProtoLogImplTest {
@@ -166,8 +164,7 @@ public class PerfettoProtoLogImplTest {
mReader = Mockito.spy(new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider));
mProtoLog = new PerfettoProtoLogImpl(
viewerConfigInputStreamProvider, mReader,
- () -> mCacheUpdater.run());
- mProtoLog.registerGroups(TestProtoLogGroup.values());
+ () -> mCacheUpdater.run(), TestProtoLogGroup.values());
}
@After
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index ab406ef4632e..5b178250a4c9 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -1867,7 +1867,7 @@ public class PackageWatchdogTest {
return true;
}
- public String getName() {
+ public String getUniqueIdentifier() {
return mName;
}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
index cb4db57bae0c..7b086784761f 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
@@ -22,6 +22,7 @@ import com.android.hoststubgen.filters.ClassWidePolicyPropagatingFilter
import com.android.hoststubgen.filters.ConstantFilter
import com.android.hoststubgen.filters.DefaultHookInjectingFilter
import com.android.hoststubgen.filters.FilterPolicy
+import com.android.hoststubgen.filters.FilterRemapper
import com.android.hoststubgen.filters.ImplicitOutputFilter
import com.android.hoststubgen.filters.OutputFilter
import com.android.hoststubgen.filters.StubIntersectingFilter
@@ -75,7 +76,9 @@ class HostStubGen(val options: HostStubGenOptions) {
}
// Build the filters.
- val (filter, policyFileRemapper) = buildFilter(errors, allClasses, options)
+ val filter = buildFilter(errors, allClasses, options)
+
+ val filterRemapper = FilterRemapper(filter)
// Transform the jar.
convert(
@@ -87,7 +90,7 @@ class HostStubGen(val options: HostStubGenOptions) {
allClasses,
errors,
stats,
- policyFileRemapper,
+ filterRemapper,
options.numShards.get,
options.shard.get,
)
@@ -117,7 +120,7 @@ class HostStubGen(val options: HostStubGenOptions) {
errors: HostStubGenErrors,
allClasses: ClassNodes,
options: HostStubGenOptions,
- ): Pair<OutputFilter, Remapper?> {
+ ): OutputFilter {
// We build a "chain" of multiple filters here.
//
// The filters are build in from "inside", meaning the first filter created here is
@@ -170,14 +173,10 @@ class HostStubGen(val options: HostStubGenOptions) {
filter,
)
- var policyFileRemapper: Remapper? = null
-
// Next, "text based" filter, which allows to override polices without touching
// the target code.
options.policyOverrideFile.ifSet {
- val (f, p) = createFilterFromTextPolicyFile(it, allClasses, filter)
- filter = f
- policyFileRemapper = p
+ filter = createFilterFromTextPolicyFile(it, allClasses, filter)
}
// If `--intersect-stub-jar` is provided, load from these jar files too.
@@ -192,7 +191,7 @@ class HostStubGen(val options: HostStubGenOptions) {
// Apply the implicit filter.
filter = ImplicitOutputFilter(errors, allClasses, filter)
- return Pair(filter, policyFileRemapper)
+ return filter
}
/**
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt
index 3f2b13aed5c0..f219dac7f0a5 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt
@@ -117,6 +117,14 @@ fun resolveClassNameWithDefaultPackage(className: String, defaultPackageName: St
return "$defaultPackageName.$className"
}
+fun splitWithLastPeriod(name: String): Pair<String, String>? {
+ val pos = name.lastIndexOf('.')
+ if (pos < 0) {
+ return null
+ }
+ return Pair(name.substring(0, pos), name.substring(pos + 1))
+}
+
fun String.toJvmClassName(): String {
return this.replace('.', '/')
}
@@ -198,11 +206,11 @@ fun writeByteCodeToReturn(methodDescriptor: String, writer: MethodVisitor) {
/**
* Given a method descriptor, insert an [argType] as the first argument to it.
*/
-fun prependArgTypeToMethodDescriptor(methodDescriptor: String, argType: Type): String {
+fun prependArgTypeToMethodDescriptor(methodDescriptor: String, classInternalName: String): String {
val returnType = Type.getReturnType(methodDescriptor)
val argTypes = Type.getArgumentTypes(methodDescriptor).toMutableList()
- argTypes.add(0, argType)
+ argTypes.add(0, Type.getType("L" + classInternalName + ";"))
return Type.getMethodDescriptor(returnType, *argTypes.toTypedArray())
}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
index cdd24e809ff8..6fcffb89924a 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
@@ -87,4 +87,23 @@ abstract class DelegatingFilter(
): List<String> {
return fallback.getMethodCallHooks(className, methodName, descriptor)
}
+
+ override fun remapType(className: String): String? {
+ return fallback.remapType(className)
+ }
+
+ override fun hasAnyMethodCallReplace(): Boolean {
+ return fallback.hasAnyMethodCallReplace()
+ }
+
+ override fun getMethodCallReplaceTo(
+ callerClassName: String,
+ callerMethodName: String,
+ className: String,
+ methodName: String,
+ descriptor: String,
+ ): MethodReplaceTarget? {
+ return fallback.getMethodCallReplaceTo(
+ callerClassName, callerMethodName, className, methodName, descriptor)
+ }
}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt
index 4d211065f1c8..f839444abb46 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt
@@ -70,7 +70,7 @@ enum class FilterPolicy {
get() = this == SubstituteAndStub || this == SubstituteAndKeep
val needsInStub: Boolean
- get() = this == Stub || this == StubClass || this == SubstituteAndStub
+ get() = this == Stub || this == StubClass || this == SubstituteAndStub || this == Ignore
val needsInImpl: Boolean
get() = this != Remove
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt
new file mode 100644
index 000000000000..c5a2f9ff5e96
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+import org.objectweb.asm.commons.Remapper
+
+/**
+ * A [Remapper] that uses [OutputFilter.remapType]
+ */
+class FilterRemapper(val filter: OutputFilter) : Remapper() {
+ private val cache = mutableMapOf<String, String>()
+
+ override fun mapType(typeInternalName: String?): String? {
+ if (typeInternalName == null) {
+ return null
+ }
+
+ cache[typeInternalName]?.let {
+ return it
+ }
+
+ var mapped = filter.remapType(typeInternalName) ?: typeInternalName
+ cache[typeInternalName] = mapped
+ return mapped
+ }
+
+ // TODO Do we need to implement mapPackage(), etc too?
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt
index 3df16ffa99b3..1049e2bf94cf 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt
@@ -89,4 +89,35 @@ abstract class OutputFilter {
List<String> {
return emptyList()
}
-} \ No newline at end of file
+
+ /**
+ * Take a class (internal) name. If the class needs to be renamed, return the new name.
+ * This is used by [FilterRemapper].
+ */
+ open fun remapType(className: String): String? {
+ return null
+ }
+
+ data class MethodReplaceTarget(val className: String, val methodName: String)
+
+ /**
+ * Return if this filter may return non-null from [getMethodCallReplaceTo].
+ * (Used for a small optimization)
+ */
+ open fun hasAnyMethodCallReplace(): Boolean {
+ return false
+ }
+
+ /**
+ * If a method call should be forwarded to another method, return the target's class / method.
+ */
+ open fun getMethodCallReplaceTo(
+ callerClassName: String,
+ callerMethodName: String,
+ className: String,
+ methodName: String,
+ descriptor: String,
+ ): MethodReplaceTarget? {
+ return null
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
index 18280034c2f4..53bcf103cad4 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
@@ -17,12 +17,13 @@ package com.android.hoststubgen.filters
import com.android.hoststubgen.ParseException
import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.asm.splitWithLastPeriod
import com.android.hoststubgen.asm.toHumanReadableClassName
+import com.android.hoststubgen.asm.toJvmClassName
import com.android.hoststubgen.log
import com.android.hoststubgen.normalizeTextLine
import com.android.hoststubgen.whitespaceRegex
import org.objectweb.asm.Opcodes
-import org.objectweb.asm.commons.Remapper
import org.objectweb.asm.tree.ClassNode
import java.io.BufferedReader
import java.io.FileReader
@@ -62,7 +63,7 @@ fun createFilterFromTextPolicyFile(
filename: String,
classes: ClassNodes,
fallback: OutputFilter,
- ): Pair<OutputFilter, Remapper?> {
+ ): OutputFilter {
log.i("Loading offloaded annotations from $filename ...")
log.withIndent {
val subclassFilter = SubclassFilter(classes, fallback)
@@ -75,7 +76,9 @@ fun createFilterFromTextPolicyFile(
var featureFlagsPolicy: FilterPolicyWithReason? = null
var syspropsPolicy: FilterPolicyWithReason? = null
var rFilePolicy: FilterPolicyWithReason? = null
- val typeRenameSpec = mutableListOf<TextFilePolicyRemapper.TypeRenameSpec>()
+ val typeRenameSpec = mutableListOf<TextFilePolicyRemapperFilter.TypeRenameSpec>()
+ val methodReplaceSpec =
+ mutableListOf<TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec>()
try {
BufferedReader(FileReader(filename)).use { reader ->
@@ -250,8 +253,24 @@ fun createFilterFromTextPolicyFile(
policy.getSubstitutionBasePolicy()
.withReason(FILTER_REASON))
- // Keep "from" -> "to" mapping.
- imf.setRenameTo(className, fromName, signature, name)
+ val classAndMethod = splitWithLastPeriod(fromName)
+ if (classAndMethod != null) {
+ // If the substitution target contains a ".", then
+ // it's a method call redirect.
+ methodReplaceSpec.add(
+ TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec(
+ className.toJvmClassName(),
+ name,
+ signature,
+ classAndMethod.first.toJvmClassName(),
+ classAndMethod.second,
+ )
+ )
+ } else {
+ // It's an in-class replace.
+ // ("@RavenwoodReplace" equivalent)
+ imf.setRenameTo(className, fromName, signature, name)
+ }
}
}
"r", "rename" -> {
@@ -267,7 +286,7 @@ fun createFilterFromTextPolicyFile(
// applied. (Which is needed for services.jar)
val prefix = fields[2].trimStart('/')
- typeRenameSpec += TextFilePolicyRemapper.TypeRenameSpec(
+ typeRenameSpec += TextFilePolicyRemapperFilter.TypeRenameSpec(
pattern, prefix)
}
@@ -281,16 +300,19 @@ fun createFilterFromTextPolicyFile(
throw e.withSourceInfo(filename, lineNo)
}
- var remapper: TextFilePolicyRemapper? = null
+ var ret: OutputFilter = imf
if (typeRenameSpec.isNotEmpty()) {
- remapper = TextFilePolicyRemapper(typeRenameSpec)
+ ret = TextFilePolicyRemapperFilter(typeRenameSpec, ret)
+ }
+ if (methodReplaceSpec.isNotEmpty()) {
+ ret = TextFilePolicyMethodReplaceFilter(methodReplaceSpec, classes, ret)
}
// Wrap the in-memory-filter with AHF.
- return Pair(
- AndroidHeuristicsFilter(
- classes, aidlPolicy, featureFlagsPolicy, syspropsPolicy, rFilePolicy, imf),
- remapper)
+ ret = AndroidHeuristicsFilter(
+ classes, aidlPolicy, featureFlagsPolicy, syspropsPolicy, rFilePolicy, ret)
+
+ return ret
}
}
@@ -330,6 +352,7 @@ private fun parsePolicy(s: String): FilterPolicy {
"r", "remove" -> FilterPolicy.Remove
"sc", "stubclass" -> FilterPolicy.StubClass
"kc", "keepclass" -> FilterPolicy.KeepClass
+ "i", "ignore" -> FilterPolicy.Ignore
else -> {
if (s.startsWith("@")) {
FilterPolicy.SubstituteAndStub
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt
new file mode 100644
index 000000000000..d45f41407a52
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+import com.android.hoststubgen.asm.ClassNodes
+
+/**
+ * Filter used by TextFileFilterPolicyParser for "method call relacement".
+ */
+class TextFilePolicyMethodReplaceFilter(
+ val spec: List<MethodCallReplaceSpec>,
+ val classes: ClassNodes,
+ val fallback: OutputFilter,
+) : DelegatingFilter(fallback) {
+
+ data class MethodCallReplaceSpec(
+ val fromClass: String,
+ val fromMethod: String,
+ val fromDescriptor: String,
+ val toClass: String,
+ val toMethod: String,
+ )
+
+ override fun hasAnyMethodCallReplace(): Boolean {
+ return true
+ }
+
+ override fun getMethodCallReplaceTo(
+ callerClassName: String,
+ callerMethodName: String,
+ className: String,
+ methodName: String,
+ descriptor: String,
+ ): MethodReplaceTarget? {
+ // Maybe use 'Tri' if we end up having too many replacements.
+ spec.forEach {
+ if (className == it.fromClass &&
+ methodName == it.fromMethod &&
+ descriptor == it.fromDescriptor
+ ) {
+ return MethodReplaceTarget(it.toClass, it.toMethod)
+ }
+ }
+ return null
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapper.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt
index 2d94bb4758ba..a78c6552b8d0 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapper.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt
@@ -16,15 +16,15 @@
package com.android.hoststubgen.filters
import com.android.hoststubgen.log
-import org.objectweb.asm.commons.Remapper
import java.util.regex.Pattern
/**
- * A [Remapper] that provides a simple "jarjar" functionality.
+ * A filter that provides a simple "jarjar" functionality via [mapType]
*/
-class TextFilePolicyRemapper(
- val typeRenameSpecs: List<TypeRenameSpec>
-) : Remapper() {
+class TextFilePolicyRemapperFilter(
+ val typeRenameSpecs: List<TypeRenameSpec>,
+ fallback: OutputFilter,
+) : DelegatingFilter(fallback) {
/**
* When a package name matches [typeInternalNamePattern], we prepend [typeInternalNamePrefix]
* to it.
@@ -36,24 +36,15 @@ class TextFilePolicyRemapper(
private val cache = mutableMapOf<String, String>()
- override fun mapType(typeInternalName: String): String {
-// if (typeInternalName == null) {
-// return null // do we need it??
-// }
- cache[typeInternalName]?.let {
- return it
- }
-
- var mapped: String = typeInternalName
+ override fun remapType(className: String): String? {
+ var mapped: String = className
typeRenameSpecs.forEach {
- if (it.typeInternalNamePattern.matcher(typeInternalName).matches()) {
- mapped = it.typeInternalNamePrefix + typeInternalName
- log.d("Renaming type $typeInternalName to $mapped")
+ if (it.typeInternalNamePattern.matcher(className).matches()) {
+ mapped = it.typeInternalNamePrefix + className
+ log.d("Renaming type $className to $mapped")
}
}
- cache[typeInternalName] = mapped
+ cache[className] = mapped
return mapped
}
-
- // TODO Do we need to implement mapPackage(), etc too?
}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
index 416b78242899..3d2e1429a30f 100644
--- a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
@@ -33,6 +33,9 @@ import com.android.hoststubgen.log
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
+import org.objectweb.asm.Opcodes.INVOKEINTERFACE
+import org.objectweb.asm.Opcodes.INVOKESTATIC
+import org.objectweb.asm.Opcodes.INVOKEVIRTUAL
import org.objectweb.asm.Type
/**
@@ -211,17 +214,14 @@ class ImplGeneratingAdapter(
}
if (policy.policy == FilterPolicy.Ignore) {
- when (Type.getReturnType(descriptor)) {
- Type.VOID_TYPE -> {
- log.v("Making method ignored...")
- return IgnoreMethodAdapter(
- access, name, descriptor, signature, exceptions, innerVisitor)
- .withAnnotation(HostStubGenProcessedAsIgnore.CLASS_DESCRIPTOR)
- }
- else -> {
- throw RuntimeException("Ignored policy only allowed for void methods")
- }
- }
+ log.v("Making method ignored...")
+ return IgnoreMethodAdapter(
+ access, name, descriptor, signature, exceptions, innerVisitor)
+ .withAnnotation(HostStubGenProcessedAsIgnore.CLASS_DESCRIPTOR)
+ }
+ if (filter.hasAnyMethodCallReplace()) {
+ innerVisitor = MethodCallReplacingAdapter(
+ access, name, descriptor, signature, exceptions, innerVisitor)
}
}
if (substituted) {
@@ -290,14 +290,37 @@ class ImplGeneratingAdapter(
*/
private inner class IgnoreMethodAdapter(
access: Int,
- val name: String,
- descriptor: String,
+ name: String,
+ val descriptor: String,
signature: String?,
exceptions: Array<String>?,
next: MethodVisitor?
) : BodyReplacingMethodVisitor(access, name, descriptor, signature, exceptions, next) {
override fun emitNewCode() {
- visitInsn(Opcodes.RETURN)
+ when (Type.getReturnType(descriptor)) {
+ Type.VOID_TYPE -> visitInsn(Opcodes.RETURN)
+ Type.BOOLEAN_TYPE, Type.BYTE_TYPE, Type.CHAR_TYPE, Type.SHORT_TYPE,
+ Type.INT_TYPE -> {
+ visitInsn(Opcodes.ICONST_0)
+ visitInsn(Opcodes.IRETURN)
+ }
+ Type.LONG_TYPE -> {
+ visitInsn(Opcodes.LCONST_0)
+ visitInsn(Opcodes.LRETURN)
+ }
+ Type.FLOAT_TYPE -> {
+ visitInsn(Opcodes.FCONST_0)
+ visitInsn(Opcodes.FRETURN)
+ }
+ Type.DOUBLE_TYPE -> {
+ visitInsn(Opcodes.DCONST_0)
+ visitInsn(Opcodes.DRETURN)
+ }
+ else -> {
+ visitInsn(Opcodes.ACONST_NULL)
+ visitInsn(Opcodes.ARETURN)
+ }
+ }
visitMaxs(0, 0) // We let ASM figure them out.
}
}
@@ -332,11 +355,9 @@ class ImplGeneratingAdapter(
// Update the descriptor -- add this class's type as the first argument
// to the method descriptor.
- val thisType = Type.getType("L" + currentClassName + ";")
-
targetDescriptor = prependArgTypeToMethodDescriptor(
- descriptor,
- thisType,
+ descriptor,
+ currentClassName,
)
// Shift the original arguments by one.
@@ -451,4 +472,61 @@ class ImplGeneratingAdapter(
false)
}
}
+
+ private inner class MethodCallReplacingAdapter(
+ access: Int,
+ val callerMethodName: String,
+ val descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ next: MethodVisitor?,
+ ) : MethodVisitor(OPCODE_VERSION, next) {
+ override fun visitMethodInsn(
+ opcode: Int,
+ owner: String?,
+ name: String?,
+ descriptor: String?,
+ isInterface: Boolean,
+ ) {
+ when (opcode) {
+ INVOKESTATIC, INVOKEVIRTUAL, INVOKEINTERFACE -> {}
+ else -> {
+ // Don't touch other opcodes.
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface)
+ return
+ }
+ }
+ val to = filter.getMethodCallReplaceTo(
+ currentClassName, callerMethodName, owner!!, name!!, descriptor!!)
+
+ if (to == null
+ // Don't replace if the target is the callsite.
+ || (to.className == currentClassName && to.methodName == callerMethodName)
+ ) {
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface)
+ return
+ }
+
+ // Replace the method call with a (static) call to the target method.
+ // If it's a non-static call, the target method's first argument will receive "this".
+ // (Because of that, we don't need to manipulate the stack. Just replace the
+ // method call.)
+
+ val toDesc = if (opcode == INVOKESTATIC) {
+ // Static call to static call, no need to change the desc.
+ descriptor
+ } else {
+ // Need to prepend the "this" type to the descriptor.
+ prependArgTypeToMethodDescriptor(descriptor, owner)
+ }
+
+ mv.visitMethodInsn(
+ INVOKESTATIC,
+ to.className,
+ to.methodName,
+ toDesc,
+ false
+ )
+ }
+ }
}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
index c127e677f84d..c2f593cf5ae3 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
@@ -1436,7 +1436,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
- interfaces: 0, fields: 3, methods: 10, attributes: 1
+ interfaces: 0, fields: 3, methods: 19, attributes: 1
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1513,6 +1513,132 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
0 8 1 foo Ljava/lang/String;
+ public java.lang.String toBeIgnoredObj();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public void toBeIgnoredV();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public boolean toBeIgnoredZ();
+ descriptor: ()Z
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public byte toBeIgnoredB();
+ descriptor: ()B
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public char toBeIgnoredC();
+ descriptor: ()C
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public short toBeIgnoredS();
+ descriptor: ()S
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public int toBeIgnoredI();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public float toBeIgnoredF();
+ descriptor: ()F
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public double toBeIgnoredD();
+ descriptor: ()D
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
public int addTwo(int);
descriptor: (I)I
flags: (0x0001) ACC_PUBLIC
@@ -1897,6 +2023,174 @@ BootstrapMethods:
InnerClasses:
public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo;
+
+ public static void startThread(java.lang.Thread);
+ descriptor: (Ljava/lang/Thread;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: iconst_1
+ x: invokevirtual #x // Method java/lang/Thread.setDaemon:(Z)V
+ x: aload_0
+ x: invokevirtual #x // Method java/lang/Thread.start:()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 thread Ljava/lang/Thread;
+
+ public static int add(int, int);
+ descriptor: (II)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_0
+ x: iload_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 a I
+ 0 4 1 b I
+}
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+InnerClasses:
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 5, attributes: 5
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace;
+
+ public static boolean nonStaticMethodCallReplaceTester() throws java.lang.Exception;
+ descriptor: ()Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=2, args_size=0
+ x: new #x // class java/util/concurrent/atomic/AtomicBoolean
+ x: dup
+ x: iconst_0
+ x: invokespecial #x // Method java/util/concurrent/atomic/AtomicBoolean."<init>":(Z)V
+ x: astore_0
+ x: new #x // class java/lang/Thread
+ x: dup
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:run:(Ljava/util/concurrent/atomic/AtomicBoolean;)Ljava/lang/Runnable;
+ x: invokespecial #x // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
+ x: astore_1
+ x: aload_1
+ x: invokevirtual #x // Method java/lang/Thread.start:()V
+ x: aload_1
+ x: invokevirtual #x // Method java/lang/Thread.join:()V
+ x: aload_0
+ x: invokevirtual #x // Method java/util/concurrent/atomic/AtomicBoolean.get:()Z
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 9 27 0 ab Ljava/util/concurrent/atomic/AtomicBoolean;
+ 23 13 1 th Ljava/lang/Thread;
+ Exceptions:
+ throws java.lang.Exception
+
+ public static int staticMethodCallReplaceTester();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: iconst_1
+ x: iconst_2
+ x: invokestatic #x // Method originalAdd:(II)I
+ x: ireturn
+ LineNumberTable:
+
+ private static int originalAdd(int, int);
+ descriptor: (II)I
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_0
+ x: iload_1
+ x: iadd
+ x: iconst_1
+ x: isub
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 a I
+ 0 6 1 b I
+
+ private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
+ descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
+ x: invokevirtual #x // Method java/lang/Thread.isDaemon:()Z
+ x: invokevirtual #x // Method java/util/concurrent/atomic/AtomicBoolean.set:(Z)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 ab Ljava/util/concurrent/atomic/AtomicBoolean;
+}
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+BootstrapMethods:
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()V
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.lambda$nonStaticMethodCallReplaceTester$0:(Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ #x ()V
+InnerClasses:
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
index 17ba48c67d98..1b83d244c55c 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
@@ -1197,7 +1197,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
- interfaces: 0, fields: 1, methods: 5, attributes: 2
+ interfaces: 0, fields: 1, methods: 14, attributes: 2
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1239,6 +1239,150 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ public java.lang.String toBeIgnoredObj();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public void toBeIgnoredV();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public boolean toBeIgnoredZ();
+ descriptor: ()Z
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public byte toBeIgnoredB();
+ descriptor: ()B
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public char toBeIgnoredC();
+ descriptor: ()C
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public short toBeIgnoredS();
+ descriptor: ()S
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public int toBeIgnoredI();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public float toBeIgnoredF();
+ descriptor: ()F
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public double toBeIgnoredD();
+ descriptor: ()D
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
public int addTwo(int);
descriptor: (I)I
flags: (0x0001) ACC_PUBLIC
@@ -1640,6 +1784,161 @@ RuntimeInvisibleAnnotations:
android.hosttest.annotation.HostSideTestStaticInitializerKeep
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static void startThread(java.lang.Thread);
+ descriptor: (Ljava/lang/Thread;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static int add(int, int);
+ descriptor: (II)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+}
+InnerClasses:
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 5
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static boolean nonStaticMethodCallReplaceTester() throws java.lang.Exception;
+ descriptor: ()Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Exceptions:
+ throws java.lang.Exception
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static int staticMethodCallReplaceTester();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
+ descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+}
+InnerClasses:
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
index 0f5f7e747a2e..d23b450c4076 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
@@ -1730,7 +1730,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
- interfaces: 0, fields: 2, methods: 8, attributes: 2
+ interfaces: 0, fields: 2, methods: 17, attributes: 2
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1825,6 +1825,140 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ public java.lang.String toBeIgnoredObj();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aconst_null
+ x: areturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public void toBeIgnoredV();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=0, locals=1, args_size=1
+ x: return
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public boolean toBeIgnoredZ();
+ descriptor: ()Z
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_0
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public byte toBeIgnoredB();
+ descriptor: ()B
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_0
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public char toBeIgnoredC();
+ descriptor: ()C
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_0
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public short toBeIgnoredS();
+ descriptor: ()S
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_0
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public int toBeIgnoredI();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_0
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public float toBeIgnoredF();
+ descriptor: ()F
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: fconst_0
+ x: freturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public double toBeIgnoredD();
+ descriptor: ()D
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: dconst_0
+ x: dreturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
public int addTwo(int);
descriptor: (I)I
flags: (0x0001) ACC_PUBLIC
@@ -2330,6 +2464,202 @@ BootstrapMethods:
#x ()Ljava/lang/Integer;
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static void startThread(java.lang.Thread);
+ descriptor: (Ljava/lang/Thread;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: iconst_1
+ x: invokevirtual #x // Method java/lang/Thread.setDaemon:(Z)V
+ x: aload_0
+ x: invokevirtual #x // Method java/lang/Thread.start:()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 thread Ljava/lang/Thread;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static int add(int, int);
+ descriptor: (II)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_0
+ x: iload_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 a I
+ 0 4 1 b I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+}
+InnerClasses:
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 6
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static boolean nonStaticMethodCallReplaceTester() throws java.lang.Exception;
+ descriptor: ()Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=2, args_size=0
+ x: new #x // class java/util/concurrent/atomic/AtomicBoolean
+ x: dup
+ x: iconst_0
+ x: invokespecial #x // Method java/util/concurrent/atomic/AtomicBoolean."<init>":(Z)V
+ x: astore_0
+ x: new #x // class java/lang/Thread
+ x: dup
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:run:(Ljava/util/concurrent/atomic/AtomicBoolean;)Ljava/lang/Runnable;
+ x: invokespecial #x // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
+ x: astore_1
+ x: aload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.startThread:(Ljava/lang/Thread;)V
+ x: aload_1
+ x: invokevirtual #x // Method java/lang/Thread.join:()V
+ x: aload_0
+ x: invokevirtual #x // Method java/util/concurrent/atomic/AtomicBoolean.get:()Z
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 9 27 0 ab Ljava/util/concurrent/atomic/AtomicBoolean;
+ 23 13 1 th Ljava/lang/Thread;
+ Exceptions:
+ throws java.lang.Exception
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static int staticMethodCallReplaceTester();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: iconst_1
+ x: iconst_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.add:(II)I
+ x: ireturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
+ descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
+ x: invokevirtual #x // Method java/lang/Thread.isDaemon:()Z
+ x: invokevirtual #x // Method java/util/concurrent/atomic/AtomicBoolean.set:(Z)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 ab Ljava/util/concurrent/atomic/AtomicBoolean;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+}
+InnerClasses:
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+BootstrapMethods:
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()V
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.lambda$nonStaticMethodCallReplaceTester$0:(Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ #x ()V
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
index 17ba48c67d98..1b83d244c55c 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
@@ -1197,7 +1197,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
- interfaces: 0, fields: 1, methods: 5, attributes: 2
+ interfaces: 0, fields: 1, methods: 14, attributes: 2
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1239,6 +1239,150 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ public java.lang.String toBeIgnoredObj();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public void toBeIgnoredV();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public boolean toBeIgnoredZ();
+ descriptor: ()Z
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public byte toBeIgnoredB();
+ descriptor: ()B
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public char toBeIgnoredC();
+ descriptor: ()C
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public short toBeIgnoredS();
+ descriptor: ()S
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public int toBeIgnoredI();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public float toBeIgnoredF();
+ descriptor: ()F
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public double toBeIgnoredD();
+ descriptor: ()D
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
public int addTwo(int);
descriptor: (I)I
flags: (0x0001) ACC_PUBLIC
@@ -1640,6 +1784,161 @@ RuntimeInvisibleAnnotations:
android.hosttest.annotation.HostSideTestStaticInitializerKeep
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static void startThread(java.lang.Thread);
+ descriptor: (Ljava/lang/Thread;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static int add(int, int);
+ descriptor: (II)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+}
+InnerClasses:
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 5
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static boolean nonStaticMethodCallReplaceTester() throws java.lang.Exception;
+ descriptor: ()Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Exceptions:
+ throws java.lang.Exception
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static int staticMethodCallReplaceTester();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
+ descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+}
+InnerClasses:
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
index 3beea643823a..d12a23d3d68f 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
@@ -2141,7 +2141,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
- interfaces: 0, fields: 2, methods: 8, attributes: 2
+ interfaces: 0, fields: 2, methods: 17, attributes: 2
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2254,13 +2254,192 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+ public java.lang.String toBeIgnoredObj();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String toBeIgnoredObj
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aconst_null
+ x: areturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public void toBeIgnoredV();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String toBeIgnoredV
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: return
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public boolean toBeIgnoredZ();
+ descriptor: ()Z
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String toBeIgnoredZ
+ x: ldc #x // String ()Z
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_0
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public byte toBeIgnoredB();
+ descriptor: ()B
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String toBeIgnoredB
+ x: ldc #x // String ()B
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_0
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public char toBeIgnoredC();
+ descriptor: ()C
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String toBeIgnoredC
+ x: ldc #x // String ()C
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_0
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public short toBeIgnoredS();
+ descriptor: ()S
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String toBeIgnoredS
+ x: ldc #x // String ()S
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_0
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public int toBeIgnoredI();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String toBeIgnoredI
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_0
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public float toBeIgnoredF();
+ descriptor: ()F
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String toBeIgnoredF
+ x: ldc #x // String ()F
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: fconst_0
+ x: freturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public double toBeIgnoredD();
+ descriptor: ()D
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String toBeIgnoredD
+ x: ldc #x // String ()D
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: dconst_0
+ x: dreturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsIgnore
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
public int addTwo(int);
descriptor: (I)I
flags: (0x0001) ACC_PUBLIC
Code:
stack=4, locals=2, args_size=2
x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
- x: ldc #x // String addTwo
+ x: ldc #x // String addTwo
x: ldc #x // String (I)I
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
@@ -2287,7 +2466,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
Code:
stack=4, locals=1, args_size=1
x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
- x: ldc #x // String nativeAddThree
+ x: ldc #x // String nativeAddThree
x: ldc #x // String (I)I
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
@@ -2313,21 +2492,21 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
Code:
stack=4, locals=1, args_size=1
x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
- x: ldc #x // String unsupportedMethod
+ x: ldc #x // String unsupportedMethod
x: ldc #x // String ()Ljava/lang/String;
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
- x: ldc #x // String unsupportedMethod
+ x: ldc #x // String unsupportedMethod
x: ldc #x // String ()Ljava/lang/String;
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
- x: new #x // class java/lang/RuntimeException
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+ x: new #x // class java/lang/RuntimeException
x: dup
- x: ldc #x // String Unreachable
- x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: ldc #x // String Unreachable
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
x: athrow
RuntimeVisibleAnnotations:
x: #x()
@@ -2341,12 +2520,12 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
Code:
stack=4, locals=1, args_size=1
x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
- x: ldc #x // String visibleButUsesUnsupportedMethod
+ x: ldc #x // String visibleButUsesUnsupportedMethod
x: ldc #x // String ()Ljava/lang/String;
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
x: aload_0
- x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
x: areturn
LineNumberTable:
LocalVariableTable:
@@ -2865,6 +3044,257 @@ BootstrapMethods:
#x ()Ljava/lang/Integer;
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 4
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static void startThread(java.lang.Thread);
+ descriptor: (Ljava/lang/Thread;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ x: ldc #x // String startThread
+ x: ldc #x // String (Ljava/lang/Thread;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iconst_1
+ x: invokevirtual #x // Method java/lang/Thread.setDaemon:(Z)V
+ x: aload_0
+ x: invokevirtual #x // Method java/lang/Thread.start:()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 thread Ljava/lang/Thread;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static int add(int, int);
+ descriptor: (II)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ x: ldc #x // String add
+ x: ldc #x // String (II)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iload_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 a I
+ 11 4 1 b I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+}
+InnerClasses:
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 5, attributes: 6
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static boolean nonStaticMethodCallReplaceTester() throws java.lang.Exception;
+ descriptor: ()Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=2, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ x: ldc #x // String nonStaticMethodCallReplaceTester
+ x: ldc #x // String ()Z
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class java/util/concurrent/atomic/AtomicBoolean
+ x: dup
+ x: iconst_0
+ x: invokespecial #x // Method java/util/concurrent/atomic/AtomicBoolean."<init>":(Z)V
+ x: astore_0
+ x: new #x // class java/lang/Thread
+ x: dup
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:run:(Ljava/util/concurrent/atomic/AtomicBoolean;)Ljava/lang/Runnable;
+ x: invokespecial #x // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
+ x: astore_1
+ x: aload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.startThread:(Ljava/lang/Thread;)V
+ x: aload_1
+ x: invokevirtual #x // Method java/lang/Thread.join:()V
+ x: aload_0
+ x: invokevirtual #x // Method java/util/concurrent/atomic/AtomicBoolean.get:()Z
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 20 27 0 ab Ljava/util/concurrent/atomic/AtomicBoolean;
+ 34 13 1 th Ljava/lang/Thread;
+ Exceptions:
+ throws java.lang.Exception
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ public static int staticMethodCallReplaceTester();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ x: ldc #x // String staticMethodCallReplaceTester
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_1
+ x: iconst_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.add:(II)I
+ x: ireturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+
+ private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
+ descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ x: ldc #x // String lambda$nonStaticMethodCallReplaceTester$0
+ x: ldc #x // String (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
+ x: invokevirtual #x // Method java/lang/Thread.isDaemon:()Z
+ x: invokevirtual #x // Method java/util/concurrent/atomic/AtomicBoolean.set:(Z)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 ab Ljava/util/concurrent/atomic/AtomicBoolean;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+}
+InnerClasses:
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInStub
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenKeptInImpl
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+BootstrapMethods:
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()V
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.lambda$nonStaticMethodCallReplaceTester$0:(Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ #x ()V
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
index 75c9721020bd..f06443362b1d 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
@@ -12,6 +12,16 @@ class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy stub
# method addThree_host (I)I # used as a substitute
method unsupportedMethod ()Ljava/lang/String; throw
method visibleButUsesUnsupportedMethod ()Ljava/lang/String; stub
+ method toBeIgnoredObj ()Ljava/lang/String; ignore
+ method toBeIgnoredV ()V ignore
+ method toBeIgnoredZ ()Z ignore
+ method toBeIgnoredB ()B ignore
+ method toBeIgnoredC ()C ignore
+ method toBeIgnoredS ()S ignore
+ method toBeIgnoredI ()I ignore
+ method toBeIgnoredL ()L ignore
+ method toBeIgnoredF ()F ignore
+ method toBeIgnoredD ()D ignore
# Class load hook
class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy ~com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
@@ -49,8 +59,18 @@ class com.android.hoststubgen.test.tinyframework.packagetest.sub.B remove
# class com.android.hoststubgen.test.tinyframework.packagetest.A stub
# class com.android.hoststubgen.test.tinyframework.packagetest.sub.A stub
+# Used to test method call replacement.
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace stubclass
+ method originalAdd (II)I @com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo.add
+
+# Used to test method call replacement.
+# Note because java.lang.Thread is _not_ within the tiny-framework jar, the policy ("keep")
+# doesn't realy matter.
+class java.lang.Thread keep
+ method start ()V @com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo.startThread
+
# "rename" takes a type internal name, so '/'s is used as a separator.
# The leading / in the prefix is not needed (it'll be stripped), but it's added to make
# sure the stripping works.
-rename ^.*/TinyFrameworkToBeRenamed$ /rename_prefix/ \ No newline at end of file
+rename ^.*/TinyFrameworkToBeRenamed$ /rename_prefix/
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.java
index bde7c35dc294..1977c900ba11 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.java
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.java
@@ -42,6 +42,42 @@ public class TinyFrameworkForTextPolicy {
throw new RuntimeException();
}
+ public String toBeIgnoredObj() {
+ throw new RuntimeException();
+ }
+
+ public void toBeIgnoredV() {
+ throw new RuntimeException();
+ }
+
+ public boolean toBeIgnoredZ() {
+ throw new RuntimeException();
+ }
+
+ public byte toBeIgnoredB() {
+ throw new RuntimeException();
+ }
+
+ public char toBeIgnoredC() {
+ throw new RuntimeException();
+ }
+
+ public short toBeIgnoredS() {
+ throw new RuntimeException();
+ }
+
+ public int toBeIgnoredI() {
+ throw new RuntimeException();
+ }
+
+ public float toBeIgnoredF() {
+ throw new RuntimeException();
+ }
+
+ public double toBeIgnoredD() {
+ throw new RuntimeException();
+ }
+
public int addTwo(int value) {
throw new RuntimeException("not supported on host side");
}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.java
new file mode 100644
index 000000000000..1ff37441c262
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestWholeClassStub;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+@HostSideTestWholeClassStub
+public class TinyFrameworkMethodCallReplace {
+ // This method should return true.
+ public static boolean nonStaticMethodCallReplaceTester() throws Exception {
+ final AtomicBoolean ab = new AtomicBoolean(false);
+
+ Thread th = new Thread(() -> {
+ ab.set(Thread.currentThread().isDaemon());
+ });
+ // This Thread.start() call will be redirected to ReplaceTo.startThread()
+ // (because of the policy file directive) which will make the thread "daemon" and start it.
+ th.start();
+ th.join();
+
+ return ab.get(); // This should be true.
+ }
+
+ public static int staticMethodCallReplaceTester() {
+ // This method call will be replaced with ReplaceTo.add().
+ return originalAdd(1, 2);
+ }
+
+ private static int originalAdd(int a, int b) {
+ return a + b - 1; // Original is broken.
+ }
+
+ public static class ReplaceTo {
+ public static void startThread(Thread thread) {
+ thread.setDaemon(true);
+ thread.start();
+ }
+
+ public static int add(int a, int b) {
+ return a + b;
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
index bf0f6545d1f5..1692c6e89e8c 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
@@ -53,6 +53,20 @@ public class TinyFrameworkClassTest {
// }
@Test
+ public void testIgnore() {
+ TinyFrameworkForTextPolicy tfc = new TinyFrameworkForTextPolicy();
+ tfc.toBeIgnoredV();
+ assertThat(tfc.toBeIgnoredZ()).isEqualTo(false);
+ assertThat(tfc.toBeIgnoredB()).isEqualTo(0);
+ assertThat(tfc.toBeIgnoredC()).isEqualTo(0);
+ assertThat(tfc.toBeIgnoredS()).isEqualTo(0);
+ assertThat(tfc.toBeIgnoredI()).isEqualTo(0);
+ assertThat(tfc.toBeIgnoredF()).isEqualTo(0);
+ assertThat(tfc.toBeIgnoredD()).isEqualTo(0);
+ assertThat(tfc.toBeIgnoredObj()).isEqualTo(null);
+ }
+
+ @Test
public void testSubstitute() {
TinyFrameworkForTextPolicy tfc = new TinyFrameworkForTextPolicy();
assertThat(tfc.addTwo(1)).isEqualTo(3);
@@ -339,4 +353,16 @@ public class TinyFrameworkClassTest {
public void testTypeRename() {
assertThat(TinyFrameworkRenamedClassCaller.foo(1)).isEqualTo(1);
}
+
+ @Test
+ public void testMethodCallReplaceNonStatic() throws Exception {
+ assertThat(TinyFrameworkMethodCallReplace.nonStaticMethodCallReplaceTester())
+ .isEqualTo(true);
+ }
+
+ @Test
+ public void testMethodCallReplaceStatic() throws Exception {
+ assertThat(TinyFrameworkMethodCallReplace.staticMethodCallReplaceTester())
+ .isEqualTo(3);
+ }
}
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
index 3c99e68cd6a0..c3595b7ac288 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
@@ -120,7 +120,7 @@ class ProtoLogCallProcessorImpl(
logCallVisitor?.processCall(call, messageString, getLevelForMethodName(
call.name.toString(), call, context), groupMap.getValue(groupName))
- } else if (call.name.id == "initialize") {
+ } else if (call.name.id == "init") {
// No processing
} else {
// Process non-log message calls