summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp14
-rw-r--r--boot/boot-image-profile-extra.txt23
-rw-r--r--cmds/idmap2/idmap2/CreateMultiple.cpp6
-rw-r--r--core/api/current.txt15
-rw-r--r--core/api/system-current.txt42
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/android/app/ActivityManagerInternal.java13
-rw-r--r--core/java/android/app/ActivityThread.java4
-rw-r--r--core/java/android/app/ITaskStackListener.aidl5
-rw-r--r--core/java/android/app/Notification.java9
-rw-r--r--core/java/android/app/TaskStackListener.java4
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java9
-rw-r--r--core/java/android/app/background_install_control_manager.aconfig7
-rw-r--r--core/java/android/appwidget/AppWidgetManager.java97
-rw-r--r--core/java/android/appwidget/flags.aconfig7
-rw-r--r--core/java/android/companion/CompanionDeviceService.java6
-rw-r--r--core/java/android/companion/virtual/IVirtualDevice.aidl5
-rw-r--r--core/java/android/companion/virtual/flags.aconfig11
-rw-r--r--core/java/android/content/pm/PackageInstaller.java11
-rw-r--r--core/java/android/content/pm/parsing/ApkLiteParseUtils.java5
-rw-r--r--core/java/android/hardware/DisplayLuts.java2
-rw-r--r--core/java/android/hardware/LutProperties.java7
-rw-r--r--core/java/android/hardware/camera2/CameraExtensionCharacteristics.java30
-rw-r--r--core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java14
-rw-r--r--core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java14
-rw-r--r--core/java/android/hardware/camera2/impl/CameraExtensionUtils.java37
-rw-r--r--core/java/android/hardware/contexthub/HubServiceInfo.java39
-rw-r--r--core/java/android/hardware/contexthub/IContextHubEndpointDiscoveryCallback.aidl36
-rw-r--r--core/java/android/hardware/contexthub/IHubEndpointDiscoveryCallback.java48
-rw-r--r--core/java/android/hardware/location/ContextHubManager.java194
-rw-r--r--core/java/android/hardware/location/IContextHubService.aidl13
-rw-r--r--core/java/android/os/CombinedMessageQueue/MessageQueue.java61
-rw-r--r--core/java/android/os/OWNERS2
-rw-r--r--core/java/android/os/flags.aconfig18
-rw-r--r--core/java/android/permission/flags.aconfig4
-rw-r--r--core/java/android/provider/Settings.java19
-rw-r--r--core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl13
-rw-r--r--core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java41
-rw-r--r--core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java145
-rw-r--r--core/java/android/service/notification/SystemZenRules.java11
-rw-r--r--core/java/android/service/quickaccesswallet/flags.aconfig7
-rw-r--r--core/java/android/view/Display.java37
-rw-r--r--core/java/android/view/DisplayInfo.java31
-rw-r--r--core/java/android/view/InputWindowHandle.java9
-rw-r--r--core/java/android/view/SurfaceControl.java7
-rw-r--r--core/java/android/view/ViewRootImpl.java7
-rw-r--r--core/java/android/view/WindowManager.java14
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java16
-rw-r--r--core/java/android/widget/RemoteViews.java6
-rw-r--r--core/java/android/window/WindowTokenClient.java8
-rw-r--r--core/java/android/window/WindowTokenClientController.java63
-rw-r--r--core/java/android/window/flags/lse_desktop_experience.aconfig47
-rw-r--r--core/java/android/window/flags/windowing_frontend.aconfig8
-rw-r--r--core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java11
-rw-r--r--core/java/com/android/internal/vibrator/persistence/SerializedCompositionPrimitive.java55
-rw-r--r--core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java15
-rw-r--r--core/java/com/android/internal/vibrator/persistence/XmlConstants.java53
-rw-r--r--core/jni/android_content_res_ApkAssets.cpp4
-rw-r--r--core/jni/android_view_SurfaceControl.cpp18
-rw-r--r--core/proto/android/providers/settings/secure.proto8
-rw-r--r--core/res/Android.bp1
-rw-r--r--core/res/AndroidManifest.xml22
-rw-r--r--core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml2
-rw-r--r--core/res/res/layout-sw600dp/preference_list_content_single.xml1
-rw-r--r--core/res/res/layout-watch-v36/alert_dialog_icon_button_wear_material3.xml123
-rw-r--r--core/res/res/layout-watch-v36/alert_dialog_material.xml24
-rw-r--r--core/res/res/layout/notification_2025_reply_container.xml79
-rw-r--r--core/res/res/layout/notification_2025_template_expanded_base.xml86
-rw-r--r--core/res/res/layout/notification_template_header.xml33
-rw-r--r--core/res/res/layout/notification_template_material_base.xml40
-rw-r--r--core/res/res/layout/notification_template_material_media.xml8
-rw-r--r--core/res/res/layout/notification_template_material_messaging.xml6
-rw-r--r--core/res/res/layout/preference_list_content.xml1
-rw-r--r--core/res/res/layout/preference_list_content_material.xml1
-rw-r--r--core/res/res/layout/preference_list_content_single.xml1
-rw-r--r--core/res/res/layout/preference_list_fragment.xml1
-rw-r--r--core/res/res/layout/preference_list_fragment_material.xml1
-rw-r--r--core/res/res/values-watch-v36/config.xml2
-rw-r--r--core/res/res/values-watch-v36/styles_material.xml6
-rw-r--r--core/res/res/values/attrs.xml7
-rw-r--r--core/res/res/values/config.xml2
-rw-r--r--core/res/res/values/ids.xml3
-rw-r--r--core/res/res/values/public-staging.xml4
-rw-r--r--core/res/res/values/strings.xml2
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/tests/coretests/Android.bp1
-rw-r--r--core/tests/coretests/AndroidTest.xml2
-rw-r--r--core/tests/coretests/src/android/app/NotificationTest.java17
-rw-r--r--core/tests/coretests/src/android/appwidget/AppWidgetEventsTest.kt51
-rw-r--r--core/tests/coretests/src/android/appwidget/OWNERS1
-rw-r--r--core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java12
-rw-r--r--core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java16
-rw-r--r--core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java82
-rw-r--r--core/xsd/permission.xsd16
-rw-r--r--core/xsd/schema/current.txt21
-rw-r--r--core/xsd/vibrator/vibration/schema/current.txt8
-rw-r--r--core/xsd/vibrator/vibration/vibration-plus-hidden-apis.xsd9
-rw-r--r--core/xsd/vibrator/vibration/vibration.xsd9
-rw-r--r--data/etc/privapp-permissions-platform.xml4
-rw-r--r--graphics/java/android/graphics/RuntimeColorFilter.java6
-rw-r--r--graphics/java/android/graphics/RuntimeShader.java11
-rw-r--r--graphics/java/android/graphics/RuntimeXfermode.java4
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java65
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducerTest.kt30
-rw-r--r--libs/WindowManager/Shell/Android.bp1
-rw-r--r--libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt97
-rw-r--r--libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt31
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/ProgressVelocityTracker.kt50
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java46
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java88
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt43
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt42
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilter.kt12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt22
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/proto/windowing_education.proto14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java8
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java42
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java18
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java39
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt89
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt31
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt21
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/MinimizeAutoPipAppWindow.kt42
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindowAndPip.kt2
-rw-r--r--libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindowAndPip.kt2
-rw-r--r--libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp1
-rw-r--r--libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt10
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java19
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt27
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt52
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt118
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt6
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt29
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationDatastoreRepositoryTest.kt16
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilterTest.kt12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java30
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/WindowingEducationTestUtils.kt12
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt4
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java13
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt65
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt16
-rw-r--r--libs/hwui/jni/ColorFilter.cpp18
-rw-r--r--libs/hwui/jni/RuntimeXfermode.cpp16
-rw-r--r--libs/hwui/jni/Shader.cpp12
-rw-r--r--media/java/android/media/AudioPlaybackConfiguration.java11
-rw-r--r--media/java/android/media/IAudioService.aidl3
-rw-r--r--media/java/android/media/MediaFormat.java25
-rw-r--r--media/java/android/media/Spatializer.java26
-rw-r--r--media/java/android/media/flags/media_better_together.aconfig8
-rw-r--r--media/java/android/media/projection/IMediaProjection.aidl3
-rw-r--r--media/java/android/media/projection/IMediaProjectionManager.aidl17
-rw-r--r--media/java/android/media/projection/MediaProjection.java2
-rw-r--r--media/java/android/media/projection/MediaProjectionManager.java4
-rw-r--r--media/java/android/media/projection/StopReason.aidl36
-rw-r--r--media/java/android/media/tv/extension/analog/IAnalogAttributeInterface.aidl26
-rw-r--r--media/java/android/media/tv/extension/cam/ICamAppInfoListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/cam/ICamAppInfoService.aidl32
-rw-r--r--media/java/android/media/tv/extension/cam/ICamDrmInfoListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/cam/ICamHostControlAskReleaseReplyCallback.aidl24
-rw-r--r--media/java/android/media/tv/extension/cam/ICamHostControlInfoListener.aidl24
-rw-r--r--media/java/android/media/tv/extension/cam/ICamHostControlService.aidl35
-rw-r--r--media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlag.aidl32
-rw-r--r--media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlagListener.aidl24
-rw-r--r--media/java/android/media/tv/extension/cam/ICamInfoListener.aidl28
-rw-r--r--media/java/android/media/tv/extension/cam/ICamMonitoringService.aidl38
-rw-r--r--media/java/android/media/tv/extension/cam/ICamPinCapabilityListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/cam/ICamPinService.aidl35
-rw-r--r--media/java/android/media/tv/extension/cam/ICamPinStatusListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/cam/ICamProfileInterface.aidl29
-rw-r--r--media/java/android/media/tv/extension/cam/IContentControlService.aidl32
-rw-r--r--media/java/android/media/tv/extension/cam/IEnterMenuErrorCallback.aidl24
-rw-r--r--media/java/android/media/tv/extension/cam/IMmiInterface.aidl32
-rw-r--r--media/java/android/media/tv/extension/cam/IMmiSession.aidl31
-rw-r--r--media/java/android/media/tv/extension/cam/IMmiStatusCallback.aidl28
-rw-r--r--media/java/android/media/tv/extension/clienttoken/IClientToken.aidl24
-rw-r--r--media/java/android/media/tv/extension/event/IEventDownload.aidl29
-rw-r--r--media/java/android/media/tv/extension/event/IEventDownloadListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/event/IEventDownloadSession.aidl38
-rw-r--r--media/java/android/media/tv/extension/event/IEventMonitor.aidl43
-rw-r--r--media/java/android/media/tv/extension/event/IEventMonitorListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl36
-rw-r--r--media/java/android/media/tv/extension/scan/IFavoriteNetworkListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl25
-rw-r--r--media/java/android/media/tv/extension/scan/ILcnConflict.aidl35
-rw-r--r--media/java/android/media/tv/extension/scan/ILcnConflictListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl35
-rw-r--r--media/java/android/media/tv/extension/scan/ILcnV2ChannelListListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/scan/IOperatorDetection.aidl35
-rw-r--r--media/java/android/media/tv/extension/scan/IOperatorDetectionListener.aidl27
-rw-r--r--media/java/android/media/tv/extension/scan/IRegionChannelList.aidl30
-rw-r--r--media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl24
-rw-r--r--media/java/android/media/tv/extension/scan/IScanInterface.aidl30
-rw-r--r--media/java/android/media/tv/extension/scan/IScanListener.aidl33
-rw-r--r--media/java/android/media/tv/extension/scan/IScanSatSearch.aidl26
-rw-r--r--media/java/android/media/tv/extension/scan/IScanSession.aidl75
-rw-r--r--media/java/android/media/tv/extension/scan/ITargetRegion.aidl36
-rw-r--r--media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/scan/ITkgsInfo.aidl28
-rw-r--r--media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdate.aidl32
-rw-r--r--media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdateListener.aidl31
-rw-r--r--media/java/android/media/tv/extension/screenmode/IScreenModeSettings.aidl29
-rw-r--r--media/java/android/media/tv/extension/servicedb/IChannelListTransfer.aidl29
-rw-r--r--media/java/android/media/tv/extension/servicedb/IServiceList.aidl30
-rw-r--r--media/java/android/media/tv/extension/servicedb/IServiceListEdit.aidl81
-rw-r--r--media/java/android/media/tv/extension/servicedb/IServiceListEditListener.aidl24
-rw-r--r--media/java/android/media/tv/extension/servicedb/IServiceListExportListener.aidl24
-rw-r--r--media/java/android/media/tv/extension/servicedb/IServiceListExportSession.aidl30
-rw-r--r--media/java/android/media/tv/extension/servicedb/IServiceListImportListener.aidl25
-rw-r--r--media/java/android/media/tv/extension/servicedb/IServiceListImportSession.aidl32
-rw-r--r--media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListListener.aidl24
-rw-r--r--media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListSession.aidl29
-rw-r--r--media/java/android/media/tv/extension/servicedb/IServiceListTransferInterface.aidl31
-rw-r--r--media/java/android/media/tv/extension/teletext/IDataServiceSignalInfo.aidl35
-rw-r--r--media/java/android/media/tv/extension/teletext/IDataServiceSignalInfoListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/teletext/ITeletextPageSubCode.aidl41
-rw-r--r--media/java/android/media/tv/extension/tune/IChannelTunedInterface.aidl27
-rw-r--r--media/java/android/media/tv/extension/tune/IChannelTunedListener.aidl26
-rw-r--r--media/java/android/media/tv/extension/tune/IMuxTune.aidl26
-rw-r--r--media/java/android/media/tv/extension/tune/IMuxTuneSession.aidl33
-rw-r--r--media/tests/projection/src/android/media/projection/FakeIMediaProjection.java2
-rw-r--r--nfc/api/current.txt2
-rw-r--r--nfc/api/system-current.txt65
-rw-r--r--nfc/java/android/nfc/INfcAdapter.aidl9
-rw-r--r--nfc/java/android/nfc/INfcCardEmulation.aidl2
-rw-r--r--nfc/java/android/nfc/IT4tNdefNfcee.aidl33
-rw-r--r--nfc/java/android/nfc/NfcAdapter.java9
-rw-r--r--nfc/java/android/nfc/NfcOemExtension.java137
-rw-r--r--nfc/java/android/nfc/NfcRoutingTableEntry.java47
-rw-r--r--nfc/java/android/nfc/RoutingTableAidEntry.java4
-rw-r--r--nfc/java/android/nfc/RoutingTableProtocolEntry.java2
-rw-r--r--nfc/java/android/nfc/RoutingTableSystemCodeEntry.java6
-rw-r--r--nfc/java/android/nfc/RoutingTableTechnologyEntry.java15
-rw-r--r--nfc/java/android/nfc/T4tNdefNfcee.java258
-rw-r--r--nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl20
-rw-r--r--nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java293
-rw-r--r--nfc/java/android/nfc/cardemulation/ApduServiceInfo.java29
-rw-r--r--nfc/java/android/nfc/cardemulation/CardEmulation.java114
-rw-r--r--packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java54
-rw-r--r--packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java14
-rw-r--r--packages/NeuralNetworks/OWNERS5
-rw-r--r--packages/SettingsLib/IntroPreference/src/com/android/settingslib/widget/IntroPreference.kt2
-rw-r--r--packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml6
-rw-r--r--packages/SettingsLib/res/drawable/ic_tv_box_internal_speaker.xml25
-rw-r--r--packages/SettingsLib/res/values/strings.xml13
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java9
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java26
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java10
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java8
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppIconCacheManagerTest.java30
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java4
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java2
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java9
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java11
-rw-r--r--packages/Shell/Android.bp2
-rw-r--r--packages/Shell/AndroidManifest.xml8
-rw-r--r--packages/StatementService/Android.bp2
-rw-r--r--packages/StatementService/src/com/android/statementservice/database/Converters.kt130
-rw-r--r--packages/StatementService/src/com/android/statementservice/database/DomainGroups.kt27
-rw-r--r--packages/StatementService/src/com/android/statementservice/database/DomainGroupsDao.kt36
-rw-r--r--packages/StatementService/src/com/android/statementservice/database/DomainGroupsDatabase.kt41
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt4
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt21
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/worker/BaseRequestWorker.kt14
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/worker/GroupUpdateV1Worker.kt55
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt46
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt10
-rw-r--r--packages/StatementService/src/com/android/statementservice/domain/worker/SingleV2RequestWorker.kt7
-rw-r--r--packages/StatementService/src/com/android/statementservice/network/retriever/StatementParser.kt19
-rw-r--r--packages/StatementService/src/com/android/statementservice/retriever/DynamicAppLinkComponent.java2
-rw-r--r--packages/StatementService/src/com/android/statementservice/retriever/JsonParser.java35
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java7
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig7
-rw-r--r--packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt48
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt13
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt43
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt18
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt3
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt4
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt7
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt1
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt31
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt3
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt69
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt25
-rw-r--r--packages/SystemUI/customization/res/values/dimens.xml1
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt11
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt203
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt145
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt65
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt98
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt122
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt10
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt43
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt120
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt63
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt28
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt116
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingStateTest.kt44
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelTest.kt63
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorTest.kt145
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt52
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt24
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt17
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java64
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt25
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt68
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt62
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockAnimations.kt61
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockConfig.kt65
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt44
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt48
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceController.kt47
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt63
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt174
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockMessageBuffers.kt30
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt87
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt25
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt529
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt110
-rw-r--r--packages/SystemUI/res/drawable/volume_background_top_legacy.xml2
-rw-r--r--packages/SystemUI/res/layout/volume_dialog_legacy.xml4
-rw-r--r--packages/SystemUI/res/values/styles.xml5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/EmergencyButton.java6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/NumPadKey.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt51
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialMetricsLogger.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt16
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt84
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt105
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt62
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt54
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeLog.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditModeButton.kt61
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt53
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt115
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt38
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingState.kt97
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt69
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModel.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractor.kt93
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt116
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java85
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java100
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationAddXOnHoverToDismiss.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.kt65
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerImpl.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java)38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt73
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt197
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt114
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java91
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt13
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/FakeMediaProjectionRepository.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt29
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorKosmos.kt25
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt1
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt31
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/Android.bp1
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt3697
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt3727
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt4896
-rwxr-xr-xravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py48
-rw-r--r--services/accessibility/accessibility.aconfig10
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java43
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java9
-rw-r--r--services/core/java/com/android/server/BinaryTransparencyService.java64
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java40
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java9
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java19
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java4
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java23
-rw-r--r--services/core/java/com/android/server/am/OWNERS3
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java21
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java1
-rw-r--r--services/core/java/com/android/server/am/flags.aconfig8
-rw-r--r--services/core/java/com/android/server/app/GameManagerService.java5
-rw-r--r--services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java3
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java13
-rw-r--r--services/core/java/com/android/server/audio/PlaybackActivityMonitor.java5
-rw-r--r--services/core/java/com/android/server/audio/SpatializerHelper.java19
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java9
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java15
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java9
-rw-r--r--services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java3
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceInfo.java10
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java14
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java18
-rw-r--r--services/core/java/com/android/server/display/LogicalDisplay.java2
-rw-r--r--services/core/java/com/android/server/display/feature/DisplayManagerFlags.java13
-rw-r--r--services/core/java/com/android/server/hdmi/Constants.java7
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java13
-rw-r--r--services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java43
-rw-r--r--services/core/java/com/android/server/inputmethod/HandwritingModeController.java10
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubService.java26
-rw-r--r--services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java20
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java63
-rw-r--r--services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java191
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java22
-rw-r--r--services/core/java/com/android/server/pm/InstallDependencyHelper.java181
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java9
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java3
-rw-r--r--services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java14
-rw-r--r--services/core/java/com/android/server/trust/TrustManagerService.java30
-rw-r--r--services/core/java/com/android/server/utils/LazyJniRegistrar.java3
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java14
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java174
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java23
-rw-r--r--services/core/java/com/android/server/wm/AppCompatController.java10
-rw-r--r--services/core/java/com/android/server/wm/ContentRecorder.java57
-rw-r--r--services/core/java/com/android/server/wm/DeferredDisplayUpdater.java1
-rw-r--r--services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java10
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java14
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java3
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java34
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java12
-rw-r--r--services/core/java/com/android/server/wm/SafeActivityOptions.java7
-rw-r--r--services/core/java/com/android/server/wm/TaskChangeNotificationController.java18
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java21
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
-rw-r--r--services/core/jni/Android.bp22
-rw-r--r--services/core/jni/com_android_server_utils_LazyJniRegistrar.cpp6
-rw-r--r--services/core/jni/onload.cpp2
-rw-r--r--services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java12
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java18
-rw-r--r--services/tests/mockingservicestests/jni/Android.bp4
-rw-r--r--services/tests/mockingservicestests/jni/onload.cpp4
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java28
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java4
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt5
-rw-r--r--services/tests/servicestests/jni/Android.bp4
-rw-r--r--services/tests/servicestests/jni/onload.cpp4
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java479
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java1444
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java33
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java47
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java197
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/SystemZenRulesTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java29
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java23
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java14
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java33
-rw-r--r--telephony/java/android/telephony/satellite/SatelliteManager.java4
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl11
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt6
-rw-r--r--tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt9
-rw-r--r--tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java2
-rw-r--r--tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java28
-rw-r--r--tools/aapt2/util/Util.h9
-rw-r--r--tools/systemfeatures/Android.bp8
-rw-r--r--tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt110
-rw-r--r--tools/systemfeatures/tests/src/PackageManager.java19
-rw-r--r--tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java36
560 files changed, 25178 insertions, 5031 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index a2994088cfb2..e18470498f39 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -100,7 +100,7 @@ aconfig_declarations_group {
"com.android.media.flags.performance-aconfig-java",
"com.android.media.flags.projection-aconfig-java",
"com.android.net.thread.platform.flags-aconfig-java",
- "com.android.ranging.flags.ranging-aconfig-java",
+ "com.android.ranging.flags.ranging-aconfig-java-export",
"com.android.server.contextualsearch.flags-java",
"com.android.server.flags.services-aconfig-java",
"com.android.text.flags-aconfig-java",
@@ -373,6 +373,11 @@ java_aconfig_library {
name: "android.security.flags-aconfig-java-export",
aconfig_declarations: "android.security.flags-aconfig",
mode: "exported",
+ min_sdk_version: "30",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.wifi",
+ ],
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
@@ -1651,13 +1656,6 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
-// Ranging
-java_aconfig_library {
- name: "com.android.ranging.flags.ranging-aconfig-java",
- aconfig_declarations: "ranging_aconfig_flags",
- defaults: ["framework-minus-apex-aconfig-java-defaults"],
-}
-
// System Server
aconfig_declarations {
name: "android.systemserver.flags-aconfig",
diff --git a/boot/boot-image-profile-extra.txt b/boot/boot-image-profile-extra.txt
index e31eb3a993f0..fd51f9cbcee1 100644
--- a/boot/boot-image-profile-extra.txt
+++ b/boot/boot-image-profile-extra.txt
@@ -23,4 +23,25 @@ HSPLandroid/graphics/Color;->luminance()F
# For now, compile all methods in MessageQueue to avoid performance cliffs for
# flagged/evolving hot code paths. See: b/338098106
HSPLandroid/os/MessageQueue;->*
-HSPLandroid/os/MessageQueue$*;->*
+HSPLandroid/os/MessageQueue$FileDescriptorRecord;->*
+HSPLandroid/os/MessageQueue$IdleHandler;->*
+HSPLandroid/os/MessageQueue$MessageCompare;->*
+HSPLandroid/os/MessageQueue$MatchAllFutureMessages;->*
+HSPLandroid/os/MessageQueue$MatchAllMessages;->*
+HSPLandroid/os/MessageQueue$MatchBarrierToken;->*
+HSPLandroid/os/MessageQueue$MatchDeliverableMessages;->*
+HSPLandroid/os/MessageQueue$MatchHandler;->*
+HSPLandroid/os/MessageQueue$MatchHandlerAndObject;->*
+HSPLandroid/os/MessageQueue$MatchHandlerAndObjectEquals;->*
+HSPLandroid/os/MessageQueue$MatchHandlerRunnableAndObject;->*
+HSPLandroid/os/MessageQueue$MatchHandlerRunnableAndObjectEquals;->*
+HSPLandroid/os/MessageQueue$MatchHandlerWhatAndObject;->*
+HSPLandroid/os/MessageQueue$MatchHandlerWhatAndObjectEquals;->*
+HSPLandroid/os/MessageQueue$MessageCounts;->*
+HSPLandroid/os/MessageQueue$StackNode;->*
+HSPLandroid/os/MessageQueue$MessageNode;->*
+HSPLandroid/os/MessageQueue$OnFileDescriptorEventListener$Events;->*
+HSPLandroid/os/MessageQueue$OnFileDescriptorEventListener;->*
+HSPLandroid/os/MessageQueue$StackNodeType;->*
+HSPLandroid/os/MessageQueue$StateNode;->*
+HSPLandroid/os/MessageQueue$TimedParkStateNode;->*
diff --git a/cmds/idmap2/idmap2/CreateMultiple.cpp b/cmds/idmap2/idmap2/CreateMultiple.cpp
index 68800cde6101..2608c69be66f 100644
--- a/cmds/idmap2/idmap2/CreateMultiple.cpp
+++ b/cmds/idmap2/idmap2/CreateMultiple.cpp
@@ -99,7 +99,7 @@ Result<Unit> CreateMultiple(const std::vector<std::string>& args) {
std::vector<std::string> idmap_paths;
for (const std::string& overlay_apk_path : overlay_apk_paths) {
- const std::string idmap_path = Idmap::CanonicalIdmapPathFor(idmap_dir, overlay_apk_path);
+ std::string idmap_path = Idmap::CanonicalIdmapPathFor(idmap_dir, overlay_apk_path);
const uid_t uid = getuid();
if (!UidHasWriteAccessToPath(uid, idmap_path)) {
LOG(WARNING) << "uid " << uid << "does not have write access to " << idmap_path.c_str();
@@ -111,7 +111,7 @@ Result<Unit> CreateMultiple(const std::vector<std::string>& args) {
!ignore_overlayable)) {
const auto overlay = OverlayResourceContainer::FromPath(overlay_apk_path);
if (!overlay) {
- LOG(WARNING) << "failed to load apk " << overlay_apk_path.c_str();
+ LOG(WARNING) << "failed to load apk " << overlay_apk_path;
continue;
}
@@ -138,7 +138,7 @@ Result<Unit> CreateMultiple(const std::vector<std::string>& args) {
}
}
- idmap_paths.emplace_back(idmap_path);
+ idmap_paths.emplace_back(std::move(idmap_path));
}
for (const std::string& idmap_path : idmap_paths) {
diff --git a/core/api/current.txt b/core/api/current.txt
index 45f6a3fbe0cb..3af8e7e17dbd 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1502,6 +1502,7 @@ package android {
field public static final int shadowRadius = 16843108; // 0x1010164
field public static final int shape = 16843162; // 0x101019a
field public static final int shareInterpolator = 16843195; // 0x10101bb
+ field @FlaggedApi("android.nfc.nfc_associated_role_services") public static final int shareRolePriority;
field @Deprecated public static final int sharedUserId = 16842763; // 0x101000b
field @Deprecated public static final int sharedUserLabel = 16843361; // 0x1010261
field public static final int sharedUserMaxSdkVersion = 16844365; // 0x101064d
@@ -2451,6 +2452,7 @@ package android {
field public static final int primary = 16908300; // 0x102000c
field public static final int progress = 16908301; // 0x102000d
field public static final int redo = 16908339; // 0x1020033
+ field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final int remoteViewsMetricsId;
field public static final int replaceText = 16908340; // 0x1020034
field public static final int secondaryProgress = 16908303; // 0x102000f
field public static final int selectAll = 16908319; // 0x102001f
@@ -9892,6 +9894,8 @@ package android.appwidget {
field public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
field public static final String ACTION_APPWIDGET_RESTORED = "android.appwidget.action.APPWIDGET_RESTORED";
field public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
+ field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EVENT_CATEGORY_APPWIDGET = "android.appwidget";
+ field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EVENT_TYPE_WIDGET_INTERACTION = "widget_interaction";
field public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
field public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds";
field public static final String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
@@ -9901,6 +9905,10 @@ package android.appwidget {
field public static final String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile";
field public static final String EXTRA_CUSTOM_EXTRAS = "customExtras";
field public static final String EXTRA_CUSTOM_INFO = "customInfo";
+ field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_CLICKED_VIEWS = "android.appwidget.extra.EVENT_CLICKED_VIEWS";
+ field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_DURATION_MS = "android.appwidget.extra.EVENT_DURATION_MS";
+ field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_POSITION_RECT = "android.appwidget.extra.EVENT_POSITION_RECT";
+ field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_SCROLLED_VIEWS = "android.appwidget.extra.EVENT_SCROLLED_VIEWS";
field public static final String EXTRA_HOST_ID = "hostId";
field public static final int INVALID_APPWIDGET_ID = 0; // 0x0
field public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
@@ -18954,6 +18962,7 @@ package android.hardware {
method @FlaggedApi("android.hardware.flags.luts_api") @NonNull public int[] getSamplingKeys();
method @FlaggedApi("android.hardware.flags.luts_api") public int getSize();
field @FlaggedApi("android.hardware.flags.luts_api") public static final int ONE_DIMENSION = 1; // 0x1
+ field @FlaggedApi("android.hardware.flags.luts_api") public static final int SAMPLING_KEY_CIE_Y = 2; // 0x2
field @FlaggedApi("android.hardware.flags.luts_api") public static final int SAMPLING_KEY_MAX_RGB = 1; // 0x1
field @FlaggedApi("android.hardware.flags.luts_api") public static final int SAMPLING_KEY_RGB = 0; // 0x0
field @FlaggedApi("android.hardware.flags.luts_api") public static final int THREE_DIMENSION = 3; // 0x3
@@ -24166,6 +24175,8 @@ package android.media {
field public static final String KEY_OPERATING_RATE = "operating-rate";
field public static final String KEY_OUTPUT_REORDER_DEPTH = "output-reorder-depth";
field public static final String KEY_PCM_ENCODING = "pcm-encoding";
+ field @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public static final String KEY_PICTURE_PROFILE_ID = "picture-profile-id";
+ field @FlaggedApi("android.media.tv.flags.apply_picture_profiles") public static final String KEY_PICTURE_PROFILE_INSTANCE = "picture-profile-instance";
field public static final String KEY_PICTURE_TYPE = "picture-type";
field public static final String KEY_PIXEL_ASPECT_RATIO_HEIGHT = "sar-height";
field public static final String KEY_PIXEL_ASPECT_RATIO_WIDTH = "sar-width";
@@ -25613,6 +25624,7 @@ package android.media {
method public void addOnSpatializerStateChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerStateChangedListener);
method public boolean canBeSpatialized(@NonNull android.media.AudioAttributes, @NonNull android.media.AudioFormat);
method public int getImmersiveAudioLevel();
+ method @FlaggedApi("android.media.audio.spatializer_capabilities") @NonNull public java.util.List<java.lang.Integer> getSpatializedChannelMasks();
method public boolean isAvailable();
method public boolean isEnabled();
method public boolean isHeadTrackerAvailable();
@@ -51925,7 +51937,7 @@ package android.view {
method public int getState();
method @FlaggedApi("com.android.server.display.feature.flags.enable_get_suggested_frame_rate") public float getSuggestedFrameRate(int);
method public android.view.Display.Mode[] getSupportedModes();
- method @Deprecated public float[] getSupportedRefreshRates();
+ method @FlaggedApi("com.android.server.display.feature.flags.enable_get_supported_refresh_rates") @NonNull public float[] getSupportedRefreshRates();
method @Deprecated public int getWidth();
method @FlaggedApi("com.android.server.display.feature.flags.enable_has_arr_support") public boolean hasArrSupport();
method public boolean isHdr();
@@ -56483,6 +56495,7 @@ package android.view.accessibility {
method public float getMin();
method public int getType();
method @Deprecated public static android.view.accessibility.AccessibilityNodeInfo.RangeInfo obtain(int, float, float, float);
+ field @FlaggedApi("android.view.accessibility.indeterminate_range_info") @NonNull public static final android.view.accessibility.AccessibilityNodeInfo.RangeInfo INDETERMINATE;
field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
field @FlaggedApi("android.view.accessibility.indeterminate_range_info") public static final int RANGE_TYPE_INDETERMINATE = 3; // 0x3
field public static final int RANGE_TYPE_INT = 0; // 0x0
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index e225bb4199e3..b7a82cde3e47 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -34,6 +34,7 @@ package android {
field public static final String ACCESS_VIBRATOR_STATE = "android.permission.ACCESS_VIBRATOR_STATE";
field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
field public static final String ADD_ALWAYS_UNLOCKED_DISPLAY = "android.permission.ADD_ALWAYS_UNLOCKED_DISPLAY";
+ field @FlaggedApi("android.companion.virtualdevice.flags.enable_limited_vdm_role") public static final String ADD_MIRROR_DISPLAY = "android.permission.ADD_MIRROR_DISPLAY";
field public static final String ADD_TRUSTED_DISPLAY = "android.permission.ADD_TRUSTED_DISPLAY";
field public static final String ADJUST_RUNTIME_PERMISSIONS_POLICY = "android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY";
field public static final String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
@@ -4249,6 +4250,7 @@ package android.content.pm {
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setPermissionsResult(int, boolean);
field public static final String ACTION_CONFIRM_INSTALL = "android.content.pm.action.CONFIRM_INSTALL";
field public static final String ACTION_CONFIRM_PRE_APPROVAL = "android.content.pm.action.CONFIRM_PRE_APPROVAL";
+ field @FlaggedApi("android.content.pm.sdk_dependency_installer") public static final String ACTION_INSTALL_DEPENDENCY = "android.content.pm.action.INSTALL_DEPENDENCY";
field public static final int DATA_LOADER_TYPE_INCREMENTAL = 2; // 0x2
field public static final int DATA_LOADER_TYPE_NONE = 0; // 0x0
field public static final int DATA_LOADER_TYPE_STREAMING = 1; // 0x1
@@ -5273,9 +5275,8 @@ package android.hardware.contexthub {
}
@FlaggedApi("android.chre.flags.offload_api") public final class HubServiceInfo implements android.os.Parcelable {
- ctor public HubServiceInfo(@NonNull String, int, int, int, @NonNull android.os.ParcelableHolder);
+ ctor public HubServiceInfo(@NonNull String, int, int, int);
method public int describeContents();
- method @NonNull public android.os.ParcelableHolder getExtendedInfo();
method public int getFormat();
method public int getMajorVersion();
method public int getMinorVersion();
@@ -5290,7 +5291,11 @@ package android.hardware.contexthub {
public static final class HubServiceInfo.Builder {
ctor public HubServiceInfo.Builder(@NonNull String, int, int, int);
method @NonNull public android.hardware.contexthub.HubServiceInfo build();
- method @NonNull public android.hardware.contexthub.HubServiceInfo.Builder setExtendedInfo(@Nullable android.os.Parcelable);
+ }
+
+ @FlaggedApi("android.chre.flags.offload_api") public interface IHubEndpointDiscoveryCallback {
+ method public void onEndpointsStarted(@NonNull java.util.List<android.hardware.contexthub.HubDiscoveryInfo>);
+ method public void onEndpointsStopped(@NonNull java.util.List<android.hardware.contexthub.HubDiscoveryInfo>);
}
@FlaggedApi("android.chre.flags.offload_api") public interface IHubEndpointLifecycleCallback {
@@ -6315,11 +6320,16 @@ package android.hardware.location {
method @Deprecated public int registerCallback(@NonNull android.hardware.location.ContextHubManager.Callback);
method @Deprecated public int registerCallback(android.hardware.location.ContextHubManager.Callback, android.os.Handler);
method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void registerEndpoint(@NonNull android.hardware.contexthub.HubEndpoint);
+ method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void registerEndpointDiscoveryCallback(long, @NonNull android.hardware.contexthub.IHubEndpointDiscoveryCallback);
+ method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void registerEndpointDiscoveryCallback(long, @NonNull android.hardware.contexthub.IHubEndpointDiscoveryCallback, @NonNull java.util.concurrent.Executor);
+ method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void registerEndpointDiscoveryCallback(@NonNull String, @NonNull android.hardware.contexthub.IHubEndpointDiscoveryCallback);
+ method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void registerEndpointDiscoveryCallback(@NonNull String, @NonNull android.hardware.contexthub.IHubEndpointDiscoveryCallback, @NonNull java.util.concurrent.Executor);
method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public int sendMessage(int, int, @NonNull android.hardware.location.ContextHubMessage);
method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public int unloadNanoApp(int);
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public android.hardware.location.ContextHubTransaction<java.lang.Void> unloadNanoApp(@NonNull android.hardware.location.ContextHubInfo, long);
method @Deprecated public int unregisterCallback(@NonNull android.hardware.location.ContextHubManager.Callback);
method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void unregisterEndpoint(@NonNull android.hardware.contexthub.HubEndpoint);
+ method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void unregisterEndpointDiscoveryCallback(@NonNull android.hardware.contexthub.IHubEndpointDiscoveryCallback);
field public static final int AUTHORIZATION_DENIED = 0; // 0x0
field public static final int AUTHORIZATION_DENIED_GRACE_PERIOD = 1; // 0x1
field public static final int AUTHORIZATION_GRANTED = 2; // 0x2
@@ -11110,6 +11120,7 @@ package android.nfc.cardemulation {
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setDynamicAidGroup(@NonNull android.nfc.cardemulation.AidGroup);
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setOffHostSecureElement(@NonNull String);
method @FlaggedApi("android.nfc.nfc_observe_mode") public void setShouldDefaultToObserveMode(boolean);
+ method @FlaggedApi("android.nfc.nfc_associated_role_services") public boolean shareRolePriority();
method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean shouldDefaultToObserveMode();
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void writeToParcel(@NonNull android.os.Parcel, int);
field @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.ApduServiceInfo> CREATOR;
@@ -12865,6 +12876,30 @@ package android.security.authenticationpolicy {
package android.security.intrusiondetection {
+ @FlaggedApi("android.security.afl_api") public final class IntrusionDetectionEvent implements android.os.Parcelable {
+ ctor public IntrusionDetectionEvent(@NonNull android.app.admin.SecurityLog.SecurityEvent);
+ ctor public IntrusionDetectionEvent(@NonNull android.app.admin.DnsEvent);
+ ctor public IntrusionDetectionEvent(@NonNull android.app.admin.ConnectEvent);
+ method @FlaggedApi("android.security.afl_api") public int describeContents();
+ method @NonNull public android.app.admin.ConnectEvent getConnectEvent();
+ method @NonNull public android.app.admin.DnsEvent getDnsEvent();
+ method @NonNull public android.app.admin.SecurityLog.SecurityEvent getSecurityEvent();
+ method @NonNull public int getType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.security.intrusiondetection.IntrusionDetectionEvent> CREATOR;
+ field public static final int NETWORK_EVENT_CONNECT = 2; // 0x2
+ field public static final int NETWORK_EVENT_DNS = 1; // 0x1
+ field public static final int SECURITY_EVENT = 0; // 0x0
+ }
+
+ @FlaggedApi("android.security.afl_api") public class IntrusionDetectionEventTransport {
+ ctor public IntrusionDetectionEventTransport();
+ method public boolean addData(@NonNull java.util.List<android.security.intrusiondetection.IntrusionDetectionEvent>);
+ method @NonNull public android.os.IBinder getBinder();
+ method public boolean initialize();
+ method public boolean release();
+ }
+
@FlaggedApi("android.security.afl_api") public class IntrusionDetectionManager {
method @RequiresPermission(android.Manifest.permission.READ_INTRUSION_DETECTION_STATE) public void addStateCallback(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.MANAGE_INTRUSION_DETECTION_STATE) public void disable(@NonNull java.util.concurrent.Executor, @NonNull android.security.intrusiondetection.IntrusionDetectionManager.CommandCallback);
@@ -16196,6 +16231,7 @@ package android.telephony {
method @Nullable @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public android.content.ComponentName getAndUpdateDefaultRespondViaMessageApplication();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallForwarding(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CallForwardingInfoCallback);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getCallWaitingStatus(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+ method @FlaggedApi("com.android.internal.telephony.flags.carrier_id_from_carrier_identifier") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public int getCarrierIdFromCarrierIdentifier(@NonNull android.service.carrier.CarrierIdentifier);
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 1a97f7beb7fa..967f6194969e 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -3730,6 +3730,7 @@ package android.view {
method @NonNull public android.view.Display.Mode getDefaultMode();
method public int getRemoveMode();
method @NonNull public int[] getReportedHdrTypes();
+ method @NonNull public float[] getSupportedRefreshRatesLegacy();
method @NonNull public android.graphics.ColorSpace[] getSupportedWideColorGamut();
method @Nullable public android.view.Display.Mode getSystemPreferredDisplayMode();
method public int getType();
@@ -3752,6 +3753,7 @@ package android.view {
public static final class Display.Mode implements android.os.Parcelable {
ctor public Display.Mode(int, int, float);
+ method public float getVsyncRate();
method public boolean isSynthetic();
method public boolean matches(int, int, float);
}
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index d9f8d33f0545..eccb6ffb281c 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -1164,6 +1164,19 @@ public abstract class ActivityManagerInternal {
@UserIdInt int userId, int notificationId);
/**
+ * Notifies that a media service associated with a media session has transitioned to a
+ * "user-engaged" state. Upon receiving this notification, service will transition to the
+ * foreground state. It should only be called by
+ * {@link com.android.server.media.MediaSessionService}
+ *
+ * @param packageName The package name of the app running the media service.
+ * @param userId The user ID associated with the service.
+ * @param notificationId The ID of the media notification associated with the service.
+ */
+ public abstract void notifyActiveMediaForegroundService(@NonNull String packageName,
+ @UserIdInt int userId, int notificationId);
+
+ /**
* Same as {@link android.app.IActivityManager#startProfile(int userId)}, but it would succeed
* even if the profile is disabled - it should only be called by
* {@link com.android.server.devicepolicy.DevicePolicyManagerService} when starting a profile
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index cb7b1153988a..f8186d68e210 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -8843,10 +8843,10 @@ public final class ActivityThread extends ClientTransactionHandler
// Call per-process mainline module initialization.
initializeMainlineModules();
- Process.setArgV0("<pre-initialized>");
-
Looper.prepareMainLooper();
+ Process.setArgV0("<pre-initialized>");
+
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
// It will be in the format "seq=114"
long startSeq = 0;
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index f2228f94ff01..4a9a28607796 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -178,6 +178,11 @@ oneway interface ITaskStackListener {
void onRecentTaskListFrozenChanged(boolean frozen);
/**
+ * Called when a task is removed from the recent tasks list as a result of adding a new task.
+ */
+ void onRecentTaskRemovedForAddTask(int taskId);
+
+ /**
* Called when a task gets or loses focus.
*
* @param taskId id of the task.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b84c91b8276b..0e68cce7a8f5 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -814,9 +814,9 @@ public class Notification implements Parcelable
if (Flags.notificationsRedesignTemplates()) {
return switch (layoutId) {
case R.layout.notification_2025_template_collapsed_base,
+ R.layout.notification_2025_template_expanded_base,
R.layout.notification_2025_template_heads_up_base,
R.layout.notification_2025_template_header,
- R.layout.notification_template_material_big_base,
R.layout.notification_template_material_big_picture,
R.layout.notification_template_material_big_text,
R.layout.notification_template_material_inbox,
@@ -3263,6 +3263,7 @@ public class Notification implements Parcelable
public boolean hasPromotableCharacteristics() {
return isColorizedRequested()
&& hasTitle()
+ && !isGroupSummary()
&& !containsCustomViews()
&& hasPromotableStyle();
}
@@ -7545,7 +7546,11 @@ public class Notification implements Parcelable
}
private int getBigBaseLayoutResource() {
- return R.layout.notification_template_material_big_base;
+ if (Flags.notificationsRedesignTemplates()) {
+ return R.layout.notification_2025_template_expanded_base;
+ } else {
+ return R.layout.notification_template_material_big_base;
+ }
}
private int getBigPictureLayoutResource() {
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 36f61fd3ef59..b9b582a7d660 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -198,6 +198,10 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
}
@Override
+ public void onRecentTaskRemovedForAddTask(int taskId) {
+ }
+
+ @Override
public void onTaskFocusChanged(int taskId, boolean focused) {
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e766ae2fce0d..42fa9e7d7994 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -14453,7 +14453,7 @@ public class DevicePolicyManager {
* </ul>
* <p>
* The following methods are supported for the parent instance but can only be called by the
- * profile owner of a managed profile that was created during the device provisioning flow:
+ * profile owner on an <a href="#organization-owned">organization owned</a> managed profile:
* <ul>
* <li>{@link #getPasswordComplexity}</li>
* <li>{@link #setCameraDisabled}</li>
@@ -14461,11 +14461,6 @@ public class DevicePolicyManager {
* <li>{@link #setAccountManagementDisabled(ComponentName, String, boolean)}</li>
* <li>{@link #setPermittedInputMethods}</li>
* <li>{@link #getPermittedInputMethods}</li>
- * </ul>
- *
- * <p>The following methods can be called by the profile owner of a managed profile
- * on an organization-owned device:
- * <ul>
* <li>{@link #wipeData}</li>
* </ul>
*
@@ -18177,4 +18172,4 @@ public class DevicePolicyManager {
}
return HEADLESS_DEVICE_OWNER_MODE_UNSUPPORTED;
}
-} \ No newline at end of file
+}
diff --git a/core/java/android/app/background_install_control_manager.aconfig b/core/java/android/app/background_install_control_manager.aconfig
index d29c5b58092d..39f10dc0647f 100644
--- a/core/java/android/app/background_install_control_manager.aconfig
+++ b/core/java/android/app/background_install_control_manager.aconfig
@@ -9,3 +9,10 @@ flag {
is_fixed_read_only: true
bug: "287507984"
}
+
+flag {
+ name: "background_install_control_callback_api"
+ namespace: "preload_safety"
+ description: "Feature flag to enable the use of push API in background install control service"
+ bug: "369382811"
+} \ No newline at end of file
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 8f20ea034cf6..40de2985f68a 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -31,6 +31,7 @@ import android.annotation.UiThread;
import android.annotation.UserIdInt;
import android.app.IServiceConnection;
import android.app.PendingIntent;
+import android.app.usage.UsageStatsManager;
import android.appwidget.flags.Flags;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
@@ -41,12 +42,14 @@ import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
+import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.HandlerThread;
import android.os.Looper;
+import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -485,6 +488,67 @@ public class AppWidgetManager {
public static final String ACTION_APPWIDGET_HOST_RESTORED
= "android.appwidget.action.APPWIDGET_HOST_RESTORED";
+ /**
+ * This is the value of {@link UsageStatsManager.EXTRA_EVENT_ACTION} in the event bundle for
+ * widget user interaction events.
+ *
+ * A single widget interaction event describes what user interactions happened during a single
+ * impression of the widget.
+ */
+ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+ public static final String EVENT_TYPE_WIDGET_INTERACTION = "widget_interaction";
+
+ /**
+ * This is the value of {@link UsageStatsManager.EXTRA_EVENT_CATEGORY} in the event bundle for
+ * widget user interaction events.
+ */
+ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+ public static final String EVENT_CATEGORY_APPWIDGET = "android.appwidget";
+
+ /**
+ * This bundle extra describes which views have been clicked during a single impression of the
+ * widget. It is an integer array of view IDs of the clicked views.
+ *
+ * Widget providers may set a different ID for event purposes by setting the
+ * {@link android.R.id.remoteViewsMetricsId} int tag on the view.
+ *
+ * @see android.views.RemoteViews.setIntTag
+ */
+ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+ public static final String EXTRA_EVENT_CLICKED_VIEWS =
+ "android.appwidget.extra.EVENT_CLICKED_VIEWS";
+
+ /**
+ * This bundle extra describes which views have been scrolled during a single impression of the
+ * widget. It is an integer array of view IDs of the scrolled views.
+ *
+ * Widget providers may set a different ID for event purposes by setting the
+ * {@link android.R.id.remoteViewsMetricsId} int tag on the view.
+ *
+ * @see android.views.RemoteViews.setIntTag
+ */
+ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+ public static final String EXTRA_EVENT_SCROLLED_VIEWS =
+ "android.appwidget.extra.EVENT_SCROLLED_VIEWS";
+
+ /**
+ * This bundle extra contains a long that represents the duration of time in milliseconds
+ * during which the widget was visible.
+ */
+ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+ public static final String EXTRA_EVENT_DURATION_MS =
+ "android.appwidget.extra.EVENT_DURATION_MS";
+
+ /**
+ * This bundle extra contains an integer array with 4 elements that describe the left, top,
+ * right, and bottom coordinates of the widget at the end of the interaction event.
+ *
+ * This Rect indicates the current position and size of the widget.
+ */
+ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+ public static final String EXTRA_EVENT_POSITION_RECT =
+ "android.appwidget.extra.EVENT_POSITION_RECT";
+
private static final String TAG = "AppWidgetManager";
private static Executor sUpdateExecutor;
@@ -1516,6 +1580,39 @@ public class AppWidgetManager {
}
}
+ /**
+ * Create a {@link PersistableBundle} that represents a single widget interaction event.
+ *
+ * @param appWidgetId App Widget ID of the widget.
+ * @param durationMs Duration of the impression in milliseconds
+ * @param position Current position of the widget.
+ * @param clickedIds IDs of views clicked during this event.
+ * @param scrolledIds IDs of views scrolled during this event.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
+ @NonNull
+ public static PersistableBundle createWidgetInteractionEvent(int appWidgetId, long durationMs,
+ @Nullable Rect position, @Nullable int[] clickedIds, @Nullable int[] scrolledIds) {
+ PersistableBundle extras = new PersistableBundle();
+ extras.putString(UsageStatsManager.EXTRA_EVENT_ACTION, EVENT_TYPE_WIDGET_INTERACTION);
+ extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY, EVENT_CATEGORY_APPWIDGET);
+ extras.putInt(EXTRA_APPWIDGET_ID, appWidgetId);
+ extras.putLong(EXTRA_EVENT_DURATION_MS, durationMs);
+ if (position != null) {
+ extras.putIntArray(EXTRA_EVENT_POSITION_RECT,
+ new int[]{position.left, position.top, position.right, position.bottom});
+ }
+ if (clickedIds != null && clickedIds.length > 0) {
+ extras.putIntArray(EXTRA_EVENT_CLICKED_VIEWS, clickedIds);
+ }
+ if (scrolledIds != null && scrolledIds.length > 0) {
+ extras.putIntArray(EXTRA_EVENT_SCROLLED_VIEWS, scrolledIds);
+ }
+ return extras;
+ }
+
@UiThread
private static @NonNull Executor createUpdateExecutorIfNull() {
diff --git a/core/java/android/appwidget/flags.aconfig b/core/java/android/appwidget/flags.aconfig
index 4499a723cfb8..17bcdb013673 100644
--- a/core/java/android/appwidget/flags.aconfig
+++ b/core/java/android/appwidget/flags.aconfig
@@ -105,3 +105,10 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "engagement_metrics"
+ namespace: "app_widgets"
+ description: "Enable collection of widget engagement metrics"
+ bug: "364655296"
+}
diff --git a/core/java/android/companion/CompanionDeviceService.java b/core/java/android/companion/CompanionDeviceService.java
index 5ad2348254e2..db080fcc7702 100644
--- a/core/java/android/companion/CompanionDeviceService.java
+++ b/core/java/android/companion/CompanionDeviceService.java
@@ -249,7 +249,7 @@ public abstract class CompanionDeviceService extends Service {
// TODO(b/315163162) Add @Deprecated keyword after 24Q2 cut.
/**
- * Called by system whenever a device associated with this app is connected.
+ * Called by the system when an associated device is nearby or connected.
*
* @param associationInfo A record for the companion device.
*/
@@ -262,7 +262,7 @@ public abstract class CompanionDeviceService extends Service {
// TODO(b/315163162) Add @Deprecated keyword after 24Q2 cut.
/**
- * Called by system whenever a device associated with this app is disconnected.
+ * Called by the system when an associated device is out of range or disconnected.
*
* @param associationInfo A record for the companion device.
*/
@@ -274,7 +274,7 @@ public abstract class CompanionDeviceService extends Service {
}
/**
- * Called by the system during device events.
+ * Called by the system when an associated device's presence state changes.
*
* @see CompanionDeviceManager#startObservingDevicePresence(ObservingDevicePresenceRequest)
*/
diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl
index d3a1c25b74d5..367f1afc912b 100644
--- a/core/java/android/companion/virtual/IVirtualDevice.aidl
+++ b/core/java/android/companion/virtual/IVirtualDevice.aidl
@@ -90,11 +90,6 @@ interface IVirtualDevice {
*/
boolean hasCustomAudioInputSupport();
- /**
- * Returns whether this device is allowed to create mirror displays.
- */
- boolean canCreateMirrorDisplays();
-
/*
* Turns off all trusted non-mirror displays of the virtual device.
*/
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index 3e6919bac5fa..46da4a3d99bc 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -81,14 +81,3 @@ flag {
description: "Enable virtual stylus input"
bug: "304829446"
}
-
-flag {
- name: "impulse_velocity_strategy_for_touch_navigation"
- is_exported: true
- namespace: "virtual_devices"
- description: "Use impulse velocity strategy during conversion of touch navigation flings into Dpad events"
- bug: "338426241"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-} \ No newline at end of file
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index cb665cd2053c..cd62573f6e4e 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -218,6 +218,17 @@ public class PackageInstaller {
"android.content.pm.action.CONFIRM_PRE_APPROVAL";
/**
+ * Intent action to be sent to the implementer of
+ * {@link android.content.pm.dependencyinstaller.DependencyInstallerService}.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_SDK_DEPENDENCY_INSTALLER)
+ @SystemApi
+ public static final String ACTION_INSTALL_DEPENDENCY =
+ "android.content.pm.action.INSTALL_DEPENDENCY";
+
+ /**
* An integer session ID that an operation is working with.
*
* @see Intent#getIntExtra(String, int)
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 72542036232c..18a45d8d442e 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -595,9 +595,6 @@ public class ApkLiteParseUtils {
/*allowDuplicates=*/ true);
break;
case TAG_USES_STATIC_LIBRARY:
- if (!android.content.pm.Flags.sdkDependencyInstaller()) {
- break;
- }
String usesStaticLibName = parser.getAttributeValue(
ANDROID_RES_NAMESPACE, "name");
long usesStaticLibVersion = parser.getAttributeIntValue(
@@ -666,7 +663,7 @@ public class ApkLiteParseUtils {
SharedLibraryInfo.TYPE_SDK_PACKAGE));
break;
case TAG_STATIC_LIBRARY:
- isSdkLibrary = true;
+ isStaticLibrary = true;
// Mirrors ParsingPackageUtils#parseStaticLibrary until lite and full
// parsing are combined
String staticLibName = parser.getAttributeValue(
diff --git a/core/java/android/hardware/DisplayLuts.java b/core/java/android/hardware/DisplayLuts.java
index 6343ba19f569..0abb30f8c24d 100644
--- a/core/java/android/hardware/DisplayLuts.java
+++ b/core/java/android/hardware/DisplayLuts.java
@@ -177,6 +177,8 @@ public final class DisplayLuts {
return "SAMPLING_KEY_RGB";
case LutProperties.SAMPLING_KEY_MAX_RGB:
return "SAMPLING_KEY_MAX_RGB";
+ case LutProperties.SAMPLING_KEY_CIE_Y:
+ return "SAMPLING_KEY_CIE_Y";
default:
return "";
}
diff --git a/core/java/android/hardware/LutProperties.java b/core/java/android/hardware/LutProperties.java
index bf40a415b0f7..abb303adac15 100644
--- a/core/java/android/hardware/LutProperties.java
+++ b/core/java/android/hardware/LutProperties.java
@@ -44,7 +44,8 @@ public final class LutProperties {
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"SAMPLING_KEY_"}, value = {
SAMPLING_KEY_RGB,
- SAMPLING_KEY_MAX_RGB
+ SAMPLING_KEY_MAX_RGB,
+ SAMPLING_KEY_CIE_Y
})
public @interface SamplingKey {
}
@@ -57,6 +58,10 @@ public final class LutProperties {
@FlaggedApi(Flags.FLAG_LUTS_API)
public static final int SAMPLING_KEY_MAX_RGB = 1;
+ /** use y of CIE XYZ as the gain value of a lut */
+ @FlaggedApi(Flags.FLAG_LUTS_API)
+ public static final int SAMPLING_KEY_CIE_Y = 2;
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
index 3cf508a6db00..58fe4774f178 100644
--- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
@@ -1066,6 +1066,7 @@ public final class CameraExtensionCharacteristics {
case ImageFormat.YUV_420_888:
case ImageFormat.JPEG:
case ImageFormat.JPEG_R:
+ case ImageFormat.DEPTH_JPEG:
case ImageFormat.YCBCR_P010:
break;
default:
@@ -1096,9 +1097,10 @@ public final class CameraExtensionCharacteristics {
// processed YUV_420 buffers.
return getSupportedSizes(
extenders.second.getSupportedPostviewResolutions(sz), format);
- } else if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010) {
- // Jpeg_R/UltraHDR + YCBCR_P010 is currently not supported in the basic
- // extension case
+ } else if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010 ||
+ (Flags.depthJpegExtensions() && (format == ImageFormat.DEPTH_JPEG))) {
+ // DepthJpeg/Jpeg_R/UltraHDR + YCBCR_P010 is currently not supported in the
+ // basic extension case
return new ArrayList<>();
} else {
throw new IllegalArgumentException("Unsupported format: " + format);
@@ -1194,8 +1196,8 @@ public final class CameraExtensionCharacteristics {
*
* <p>Device-specific extensions currently support at most three
* multi-frame capture surface formats. ImageFormat.JPEG will be supported by all
- * extensions while ImageFormat.YUV_420_888, ImageFormat.JPEG_R, or ImageFormat.YCBCR_P010
- * may or may not be supported.</p>
+ * extensions while ImageFormat.YUV_420_888, ImageFormat.JPEG_R, ImageFormat.YCBCR_P010 or
+ * ImageFormat.DEPTH_JPEG may or may not be supported.</p>
*
* @param extension the extension type
* @param format device-specific extension output format
@@ -1203,7 +1205,8 @@ public final class CameraExtensionCharacteristics {
* supported.
* @throws IllegalArgumentException in case of format different from ImageFormat.JPEG,
* ImageFormat.YUV_420_888, ImageFormat.JPEG_R,
- * ImageFormat.YCBCR_P010; or unsupported extension.
+ * ImageFormat.DEPTH_JPEG, ImageFormat.YCBCR_P010; or
+ * unsupported extension.
*/
public @NonNull
List<Size> getExtensionSupportedSizes(@Extension int extension, int format) {
@@ -1227,6 +1230,7 @@ public final class CameraExtensionCharacteristics {
case ImageFormat.YUV_420_888:
case ImageFormat.JPEG:
case ImageFormat.JPEG_R:
+ case ImageFormat.DEPTH_JPEG:
case ImageFormat.YCBCR_P010:
break;
default:
@@ -1260,8 +1264,9 @@ public final class CameraExtensionCharacteristics {
} else {
return generateSupportedSizes(null, format, streamMap);
}
- } else if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010) {
- // Jpeg_R/UltraHDR + YCBCR_P010 is currently not supported in the
+ } else if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010 ||
+ (Flags.depthJpegExtensions() && (format == ImageFormat.DEPTH_JPEG))) {
+ // DepthJpeg/Jpeg_R/UltraHDR + YCBCR_P010 is currently not supported in the
// basic extension case
return new ArrayList<>();
} else {
@@ -1292,7 +1297,8 @@ public final class CameraExtensionCharacteristics {
* or null if no capture latency info can be provided
* @throws IllegalArgumentException in case of format different from {@link ImageFormat#JPEG},
* {@link ImageFormat#YUV_420_888}, {@link ImageFormat#JPEG_R}
- * {@link ImageFormat#YCBCR_P010};
+ * {@link ImageFormat#YCBCR_P010},
+ * {@link ImageFormat#DEPTH_JPEG};
* or unsupported extension.
*/
public @Nullable Range<Long> getEstimatedCaptureLatencyRangeMillis(@Extension int extension,
@@ -1301,6 +1307,7 @@ public final class CameraExtensionCharacteristics {
case ImageFormat.YUV_420_888:
case ImageFormat.JPEG:
case ImageFormat.JPEG_R:
+ case ImageFormat.DEPTH_JPEG:
case ImageFormat.YCBCR_P010:
//No op
break;
@@ -1349,8 +1356,9 @@ public final class CameraExtensionCharacteristics {
// specific and cannot be estimated accurately enough.
return null;
}
- if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010) {
- // JpegR/UltraHDR + YCBCR_P010 is not supported for basic extensions
+ if (format == ImageFormat.JPEG_R || format == ImageFormat.YCBCR_P010 ||
+ (Flags.depthJpegExtensions() && (format == ImageFormat.DEPTH_JPEG))) {
+ // DepthJpeg/JpegR/UltraHDR + YCBCR_P010 is not supported for basic extensions
return null;
}
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index fc03b517e6d4..d511e9f64c17 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -186,12 +186,12 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
HashMap<Integer, List<Size>> supportedCaptureSizes = new HashMap<>();
- IntArray supportedCaptureOutputFormats =
- new IntArray(CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.length);
- supportedCaptureOutputFormats.addAll(
- CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS);
- supportedCaptureOutputFormats.add(ImageFormat.YCBCR_P010);
- for (int format : supportedCaptureOutputFormats.toArray()) {
+ Integer[] supportedCaptureOutputFormats =
+ new Integer[CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.size()];
+ supportedCaptureOutputFormats =
+ CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.toArray(
+ supportedCaptureOutputFormats);
+ for (int format : supportedCaptureOutputFormats) {
List<Size> supportedSizes = extensionChars.getExtensionSupportedSizes(
config.getExtension(), format);
if (supportedSizes != null) {
@@ -230,7 +230,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
Size burstCaptureSurfaceSize =
new Size(burstCaptureSurfaceInfo.mWidth, burstCaptureSurfaceInfo.mHeight);
HashMap<Integer, List<Size>> supportedPostviewSizes = new HashMap<>();
- for (int format : supportedCaptureOutputFormats.toArray()) {
+ for (int format : supportedCaptureOutputFormats) {
List<Size> supportedSizesPostview = extensionChars.getPostviewSupportedSizes(
config.getExtension(), burstCaptureSurfaceSize, format);
if (supportedSizesPostview != null) {
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index ce1609dec4e6..ed73e624e242 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -186,12 +186,12 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
}
HashMap<Integer, List<Size>> supportedCaptureSizes = new HashMap<>();
- IntArray supportedCaptureOutputFormats =
- new IntArray(CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.length);
- supportedCaptureOutputFormats.addAll(
- CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS);
- supportedCaptureOutputFormats.add(ImageFormat.YCBCR_P010);
- for (int format : supportedCaptureOutputFormats.toArray()) {
+ Integer[] supportedCaptureOutputFormats =
+ new Integer[CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.size()];
+ supportedCaptureOutputFormats =
+ CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.toArray(
+ supportedCaptureOutputFormats);
+ for (int format : supportedCaptureOutputFormats) {
List<Size> supportedSizes = extensionChars.getExtensionSupportedSizes(
config.getExtension(), format);
if (supportedSizes != null) {
@@ -223,7 +223,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
Size burstCaptureSurfaceSize =
new Size(burstCaptureSurfaceInfo.mWidth, burstCaptureSurfaceInfo.mHeight);
HashMap<Integer, List<Size>> supportedPostviewSizes = new HashMap<>();
- for (int format : supportedCaptureOutputFormats.toArray()) {
+ for (int format : supportedCaptureOutputFormats) {
List<Size> supportedSizesPostview = extensionChars.getPostviewSupportedSizes(
config.getExtension(), burstCaptureSurfaceSize, format);
if (supportedSizesPostview != null) {
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java b/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java
index f91d277d571f..212c909bcbba 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionUtils.java
@@ -32,11 +32,14 @@ import android.os.Handler;
import android.util.IntArray;
import android.util.Log;
import android.util.Size;
+import android.util.SparseIntArray;
import android.view.Surface;
import com.android.internal.camera.flags.Flags;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
@@ -48,11 +51,16 @@ public final class CameraExtensionUtils {
public final static int JPEG_DEFAULT_QUALITY = 100;
public final static int JPEG_DEFAULT_ROTATION = 0;
- public static final int[] SUPPORTED_CAPTURE_OUTPUT_FORMATS = {
- CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT,
- ImageFormat.JPEG,
- ImageFormat.JPEG_R
- };
+ public static HashSet<Integer> SUPPORTED_CAPTURE_OUTPUT_FORMATS = new HashSet<>();
+
+ static {
+ SUPPORTED_CAPTURE_OUTPUT_FORMATS.addAll(Arrays.asList(
+ CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT, ImageFormat.JPEG,
+ ImageFormat.YCBCR_P010, ImageFormat.JPEG_R ));
+ if (Flags.depthJpegExtensions()) {
+ SUPPORTED_CAPTURE_OUTPUT_FORMATS.add(ImageFormat.DEPTH_JPEG);
+ }
+ }
public static class SurfaceInfo {
public int mWidth = 0;
@@ -101,6 +109,13 @@ public final class CameraExtensionUtils {
surfaceInfo.mFormat = ImageFormat.JPEG_R;
return surfaceInfo;
}
+ if (Flags.depthJpegExtensions()) {
+ if ((nativeFormat == StreamConfigurationMap.HAL_PIXEL_FORMAT_BLOB)
+ && (dataspace == StreamConfigurationMap.HAL_DATASPACE_DYNAMIC_DEPTH)) {
+ surfaceInfo.mFormat = ImageFormat.DEPTH_JPEG;
+ return surfaceInfo;
+ }
+ }
return surfaceInfo;
}
@@ -125,14 +140,14 @@ public final class CameraExtensionUtils {
public static Surface getBurstCaptureSurface(
@NonNull List<OutputConfiguration> outputConfigs,
@NonNull HashMap<Integer, List<Size>> supportedCaptureSizes) {
- IntArray supportedCaptureOutputFormats =
- new IntArray(CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.length);
- supportedCaptureOutputFormats.addAll(
- CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS);
- supportedCaptureOutputFormats.add(ImageFormat.YCBCR_P010);
+ Integer[] supportedCaptureOutputFormats =
+ new Integer[CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.size()];
+ supportedCaptureOutputFormats =
+ CameraExtensionUtils.SUPPORTED_CAPTURE_OUTPUT_FORMATS.toArray(
+ supportedCaptureOutputFormats);
for (OutputConfiguration config : outputConfigs) {
SurfaceInfo surfaceInfo = querySurface(config.getSurface());
- for (int supportedFormat : supportedCaptureOutputFormats.toArray()) {
+ for (int supportedFormat : supportedCaptureOutputFormats) {
if (surfaceInfo.mFormat == supportedFormat) {
Size captureSize = new Size(surfaceInfo.mWidth, surfaceInfo.mHeight);
if (supportedCaptureSizes.containsKey(supportedFormat)) {
diff --git a/core/java/android/hardware/contexthub/HubServiceInfo.java b/core/java/android/hardware/contexthub/HubServiceInfo.java
index c7fe77c4a0f1..a1c52fb5864f 100644
--- a/core/java/android/hardware/contexthub/HubServiceInfo.java
+++ b/core/java/android/hardware/contexthub/HubServiceInfo.java
@@ -17,12 +17,10 @@ package android.hardware.contexthub;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
-import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.chre.flags.Flags;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.ParcelableHolder;
import androidx.annotation.NonNull;
@@ -76,15 +74,12 @@ public final class HubServiceInfo implements Parcelable {
private final int mMajorVersion;
private final int mMinorVersion;
- @NonNull private final ParcelableHolder mExtendedInfo;
-
/** @hide */
public HubServiceInfo(android.hardware.contexthub.Service service) {
mServiceDescriptor = service.serviceDescriptor;
mFormat = service.format;
mMajorVersion = service.majorVersion;
mMinorVersion = service.minorVersion;
- mExtendedInfo = service.extendedInfo;
}
private HubServiceInfo(Parcel in) {
@@ -92,20 +87,17 @@ public final class HubServiceInfo implements Parcelable {
mFormat = in.readInt();
mMajorVersion = in.readInt();
mMinorVersion = in.readInt();
- mExtendedInfo = ParcelableHolder.CREATOR.createFromParcel(in);
}
public HubServiceInfo(
@NonNull String serviceDescriptor,
@ServiceFormat int format,
int majorVersion,
- int minorVersion,
- @NonNull ParcelableHolder extendedInfo) {
+ int minorVersion) {
mServiceDescriptor = serviceDescriptor;
mFormat = format;
mMajorVersion = majorVersion;
mMinorVersion = minorVersion;
- mExtendedInfo = extendedInfo;
}
/** Get the unique identifier of this service. See {@link Builder} for more information. */
@@ -134,17 +126,10 @@ public final class HubServiceInfo implements Parcelable {
return mMinorVersion;
}
- /** Get the {@link ParcelableHolder} for the extended information about the service. */
- @NonNull
- public ParcelableHolder getExtendedInfo() {
- return mExtendedInfo;
- }
-
/** Parcel implementation details */
@Override
public int describeContents() {
- // Passthrough describeContents flags for mExtendedInfo because we don't have FD otherwise.
- return mExtendedInfo.describeContents();
+ return 0;
}
/** Parcel implementation details */
@@ -154,7 +139,6 @@ public final class HubServiceInfo implements Parcelable {
dest.writeInt(mFormat);
dest.writeInt(mMajorVersion);
dest.writeInt(mMinorVersion);
- mExtendedInfo.writeToParcel(dest, flags);
}
/** Builder for a {@link HubServiceInfo} object. */
@@ -165,9 +149,6 @@ public final class HubServiceInfo implements Parcelable {
private final int mMajorVersion;
private final int mMinorVersion;
- private final ParcelableHolder mExtendedInfo =
- new ParcelableHolder(Parcelable.PARCELABLE_STABILITY_VINTF);
-
/**
* Create a builder for {@link HubServiceInfo} with a service descriptor.
*
@@ -220,20 +201,6 @@ public final class HubServiceInfo implements Parcelable {
}
/**
- * Set the extended information of this service.
- *
- * @param extendedInfo Parcelable with extended information about this service. The
- * parcelable needs to have at least VINTF stability. Null can be used to clear a
- * previously set value.
- * @throws android.os.BadParcelableException if the parcelable cannot be used.
- */
- @NonNull
- public Builder setExtendedInfo(@Nullable Parcelable extendedInfo) {
- mExtendedInfo.setParcelable(extendedInfo);
- return this;
- }
-
- /**
* Build the {@link HubServiceInfo} object.
*
* @throws IllegalStateException if the Builder is missing required info.
@@ -244,7 +211,7 @@ public final class HubServiceInfo implements Parcelable {
throw new IllegalStateException("Major and minor version must be set.");
}
return new HubServiceInfo(
- mServiceDescriptor, mFormat, mMajorVersion, mMinorVersion, mExtendedInfo);
+ mServiceDescriptor, mFormat, mMajorVersion, mMinorVersion);
}
}
diff --git a/core/java/android/hardware/contexthub/IContextHubEndpointDiscoveryCallback.aidl b/core/java/android/hardware/contexthub/IContextHubEndpointDiscoveryCallback.aidl
new file mode 100644
index 000000000000..85775c05bad9
--- /dev/null
+++ b/core/java/android/hardware/contexthub/IContextHubEndpointDiscoveryCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 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.hardware.contexthub;
+
+import android.hardware.contexthub.HubEndpointInfo;
+
+/**
+ * @hide
+ */
+oneway interface IContextHubEndpointDiscoveryCallback {
+ /**
+ * Called when endpoint(s) start.
+ * @param hubEndpointInfoList The list of endpoints that started.
+ */
+ void onEndpointsStarted(in HubEndpointInfo[] hubEndpointInfoList);
+
+ /**
+ * Called when endpoint(s) stopped.
+ * @param hubEndpointInfoList The list of endpoints that started.
+ */
+ void onEndpointsStopped(in HubEndpointInfo[] hubEndpointInfoList);
+}
diff --git a/core/java/android/hardware/contexthub/IHubEndpointDiscoveryCallback.java b/core/java/android/hardware/contexthub/IHubEndpointDiscoveryCallback.java
new file mode 100644
index 000000000000..0b77ddb8cb0b
--- /dev/null
+++ b/core/java/android/hardware/contexthub/IHubEndpointDiscoveryCallback.java
@@ -0,0 +1,48 @@
+/*
+ * 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.hardware.contexthub;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.chre.flags.Flags;
+
+import java.util.List;
+
+/**
+ * Interface for listening to updates about endpoint availability.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_OFFLOAD_API)
+public interface IHubEndpointDiscoveryCallback {
+ /**
+ * Called when a list of hub endpoints have started.
+ *
+ * @param discoveryInfoList The list containing hub discovery information.
+ */
+ void onEndpointsStarted(@NonNull List<HubDiscoveryInfo> discoveryInfoList);
+
+ /**
+ * Called when a list of hub endpoints have stopped.
+ *
+ * @param discoveryInfoList The list containing hub discovery information.
+ */
+ // TODO(b/375487784): Add endpoint stop reason
+ void onEndpointsStopped(@NonNull List<HubDiscoveryInfo> discoveryInfoList);
+}
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 426cd69f76a0..5e8a18724cdf 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -38,6 +38,8 @@ import android.hardware.contexthub.HubDiscoveryInfo;
import android.hardware.contexthub.HubEndpoint;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.HubServiceInfo;
+import android.hardware.contexthub.IContextHubEndpointDiscoveryCallback;
+import android.hardware.contexthub.IHubEndpointDiscoveryCallback;
import android.hardware.contexthub.IHubEndpointLifecycleCallback;
import android.os.Handler;
import android.os.HandlerExecutor;
@@ -49,7 +51,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
/**
@@ -202,6 +206,10 @@ public final class ContextHubManager {
private Callback mCallback;
private Handler mCallbackHandler;
+ /** A map of endpoint discovery callbacks currently registered */
+ private Map<IHubEndpointDiscoveryCallback, IContextHubEndpointDiscoveryCallback>
+ mDiscoveryCallbacks = new ConcurrentHashMap<>();
+
/**
* @deprecated Use {@code mCallback} instead.
*/
@@ -694,8 +702,6 @@ public final class ContextHubManager {
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@NonNull
public List<HubDiscoveryInfo> findEndpoints(long endpointId) {
- // TODO(b/379323274): Consider improving these getters to avoid racing with nano app load
- // timing.
try {
List<HubEndpointInfo> endpointInfos = mService.findEndpoints(endpointId);
List<HubDiscoveryInfo> results = new ArrayList<>(endpointInfos.size());
@@ -720,8 +726,6 @@ public final class ContextHubManager {
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@NonNull
public List<HubDiscoveryInfo> findEndpoints(@NonNull String serviceDescriptor) {
- // TODO(b/379323274): Consider improving these getters to avoid racing with nano app load
- // timing.
if (serviceDescriptor.isBlank()) {
throw new IllegalArgumentException("Invalid service descriptor: " + serviceDescriptor);
}
@@ -744,6 +748,188 @@ public final class ContextHubManager {
}
/**
+ * Creates an interface to invoke endpoint discovery callbacks to send down to the service.
+ *
+ * @param callback the callback to invoke at the client process
+ * @param executor the executor to invoke callbacks for this client
+ * @return the callback interface
+ */
+ private IContextHubEndpointDiscoveryCallback createDiscoveryCallback(
+ IHubEndpointDiscoveryCallback callback,
+ Executor executor,
+ @Nullable String serviceDescriptor) {
+ return new IContextHubEndpointDiscoveryCallback.Stub() {
+ @Override
+ public void onEndpointsStarted(HubEndpointInfo[] hubEndpointInfoList) {
+ if (hubEndpointInfoList.length == 0) {
+ Log.w(TAG, "onEndpointsStarted: received empty discovery list");
+ return;
+ }
+ executor.execute(
+ () -> {
+ // TODO(b/380293951): Refactor
+ List<HubDiscoveryInfo> discoveryList =
+ new ArrayList<>(hubEndpointInfoList.length);
+ for (HubEndpointInfo info : hubEndpointInfoList) {
+ if (serviceDescriptor != null) {
+ for (HubServiceInfo sInfo : info.getServiceInfoCollection()) {
+ if (sInfo.getServiceDescriptor()
+ .equals(serviceDescriptor)) {
+ discoveryList.add(new HubDiscoveryInfo(info, sInfo));
+ }
+ }
+ } else {
+ discoveryList.add(new HubDiscoveryInfo(info));
+ }
+ }
+ if (discoveryList.isEmpty()) {
+ Log.w(TAG, "onEndpointsStarted: no matching service descriptor");
+ } else {
+ callback.onEndpointsStarted(discoveryList);
+ }
+ });
+ }
+
+ @Override
+ public void onEndpointsStopped(HubEndpointInfo[] hubEndpointInfoList) {
+ if (hubEndpointInfoList.length == 0) {
+ Log.w(TAG, "onEndpointsStopped: received empty discovery list");
+ return;
+ }
+ executor.execute(
+ () -> {
+ List<HubDiscoveryInfo> discoveryList =
+ new ArrayList<>(hubEndpointInfoList.length);
+ for (HubEndpointInfo info : hubEndpointInfoList) {
+ if (serviceDescriptor != null) {
+ for (HubServiceInfo sInfo : info.getServiceInfoCollection()) {
+ if (sInfo.getServiceDescriptor()
+ .equals(serviceDescriptor)) {
+ discoveryList.add(new HubDiscoveryInfo(info, sInfo));
+ }
+ }
+ } else {
+ discoveryList.add(new HubDiscoveryInfo(info));
+ }
+ }
+ if (discoveryList.isEmpty()) {
+ Log.w(TAG, "onEndpointsStopped: no matching service descriptor");
+ } else {
+ callback.onEndpointsStopped(discoveryList);
+ }
+ });
+ }
+ };
+ }
+
+ /**
+ * Equivalent to {@link #registerEndpointDiscoveryCallback(long, IHubEndpointDiscoveryCallback,
+ * Executor)} with the default executor in the main thread.
+ */
+ @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+ @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+ public void registerEndpointDiscoveryCallback(
+ long endpointId, @NonNull IHubEndpointDiscoveryCallback callback) {
+ registerEndpointDiscoveryCallback(
+ endpointId, callback, new HandlerExecutor(Handler.getMain()));
+ }
+
+ /**
+ * Registers a callback to be notified when the hub endpoint with the corresponding endpoint ID
+ * has started or stopped.
+ *
+ * @param endpointId The identifier of the hub endpoint.
+ * @param callback The callback to be invoked.
+ * @param executor The executor to invoke the callback on.
+ */
+ @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+ @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+ public void registerEndpointDiscoveryCallback(
+ long endpointId,
+ @NonNull IHubEndpointDiscoveryCallback callback,
+ @NonNull Executor executor) {
+ Objects.requireNonNull(callback, "callback cannot be null");
+ Objects.requireNonNull(executor, "executor cannot be null");
+ IContextHubEndpointDiscoveryCallback iCallback =
+ createDiscoveryCallback(callback, executor, null);
+ try {
+ mService.registerEndpointDiscoveryCallbackId(endpointId, iCallback);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+
+ mDiscoveryCallbacks.put(callback, iCallback);
+ }
+
+ /**
+ * Equivalent to {@link #registerEndpointDiscoveryCallback(String,
+ * IHubEndpointDiscoveryCallback, Executor)} with the default executor in the main thread.
+ */
+ @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+ @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+ public void registerEndpointDiscoveryCallback(
+ @NonNull String serviceDescriptor, @NonNull IHubEndpointDiscoveryCallback callback) {
+ registerEndpointDiscoveryCallback(
+ serviceDescriptor, callback, new HandlerExecutor(Handler.getMain()));
+ }
+
+ /**
+ * Registers a callback to be notified when the hub endpoint with the corresponding service
+ * descriptor has started or stopped.
+ *
+ * @param serviceDescriptor The service descriptor of the hub endpoint.
+ * @param callback The callback to be invoked.
+ * @param executor The executor to invoke the callback on.
+ * @throws IllegalArgumentException if the serviceDescriptor is empty.
+ */
+ @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+ @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+ public void registerEndpointDiscoveryCallback(
+ @NonNull String serviceDescriptor,
+ @NonNull IHubEndpointDiscoveryCallback callback,
+ @NonNull Executor executor) {
+ Objects.requireNonNull(serviceDescriptor, "serviceDescriptor cannot be null");
+ Objects.requireNonNull(callback, "callback cannot be null");
+ Objects.requireNonNull(executor, "executor cannot be null");
+ if (serviceDescriptor.isBlank()) {
+ throw new IllegalArgumentException("Invalid service descriptor: " + serviceDescriptor);
+ }
+
+ IContextHubEndpointDiscoveryCallback iCallback =
+ createDiscoveryCallback(callback, executor, serviceDescriptor);
+ try {
+ mService.registerEndpointDiscoveryCallbackDescriptor(serviceDescriptor, iCallback);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+
+ mDiscoveryCallbacks.put(callback, iCallback);
+ }
+
+ /**
+ * Unregisters a previously registered endpoint discovery callback.
+ *
+ * @param callback The callback previously registered.
+ * @throws IllegalArgumentException If the callback was not previously registered.
+ */
+ @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+ @FlaggedApi(Flags.FLAG_OFFLOAD_API)
+ public void unregisterEndpointDiscoveryCallback(
+ @NonNull IHubEndpointDiscoveryCallback callback) {
+ Objects.requireNonNull(callback, "callback cannot be null");
+ IContextHubEndpointDiscoveryCallback iCallback = mDiscoveryCallbacks.remove(callback);
+ if (iCallback == null) {
+ throw new IllegalArgumentException("Callback not previously registered");
+ }
+
+ try {
+ mService.unregisterEndpointDiscoveryCallback(iCallback);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Set a callback to receive messages from the context hub
*
* @param callback Callback object
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
index f9f412446038..f14aadcab474 100644
--- a/core/java/android/hardware/location/IContextHubService.aidl
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -21,6 +21,7 @@ import android.app.PendingIntent;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.IContextHubEndpoint;
import android.hardware.contexthub.IContextHubEndpointCallback;
+import android.hardware.contexthub.IContextHubEndpointDiscoveryCallback;
import android.hardware.location.ContextHubInfo;
import android.hardware.location.ContextHubMessage;
import android.hardware.location.HubInfo;
@@ -137,4 +138,16 @@ interface IContextHubService {
// Register an endpoint with the context hub
@EnforcePermission("ACCESS_CONTEXT_HUB")
IContextHubEndpoint registerEndpoint(in HubEndpointInfo pendingEndpointInfo, in IContextHubEndpointCallback callback);
+
+ // Register an endpoint discovery callback (id)
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
+ void registerEndpointDiscoveryCallbackId(long endpointId, in IContextHubEndpointDiscoveryCallback callback);
+
+ // Register an endpoint discovery callback (descriptor)
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
+ void registerEndpointDiscoveryCallbackDescriptor(String serviceDescriptor, in IContextHubEndpointDiscoveryCallback callback);
+
+ // Unregister an endpoint with the context hub
+ @EnforcePermission("ACCESS_CONTEXT_HUB")
+ void unregisterEndpointDiscoveryCallback(in IContextHubEndpointDiscoveryCallback callback);
}
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 4c9f08d80d4b..3e4d74546adc 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -19,8 +19,6 @@ package android.os;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.TestApi;
-import android.app.ActivityThread;
-import android.app.Instrumentation;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Process;
import android.os.UserHandle;
@@ -88,14 +86,20 @@ public final class MessageQueue {
// queue for async messages when inserting a message at the tail.
private int mAsyncMessageCount;
- /*
+ /**
* Select between two implementations of message queue. The legacy implementation is used
* by default as it provides maximum compatibility with applications and tests that
* reach into MessageQueue via the mMessages field. The concurrent implemmentation is used for
* system processes and provides a higher level of concurrency and higher enqueue throughput
* than the legacy implementation.
*/
- private boolean mUseConcurrent;
+ private final boolean mUseConcurrent;
+
+ /**
+ * Caches process-level checks that determine `mUseConcurrent`.
+ * This is to avoid redoing checks that shouldn't change during the process's lifetime.
+ */
+ private static Boolean sIsProcessAllowedToUseConcurrent = null;
@RavenwoodRedirect
private native static long nativeInit();
@@ -112,32 +116,37 @@ public final class MessageQueue {
private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
MessageQueue(boolean quitAllowed) {
- // Concurrent mode modifies behavior that is observable via reflection and is commonly used
- // by tests.
- // For now, we limit it to system processes to avoid breaking apps and their tests.
- mUseConcurrent = UserHandle.isCore(Process.myUid());
- // Even then, we don't use it if instrumentation is loaded as it breaks some
- // platform tests.
- final Instrumentation instrumentation = getInstrumentation();
- mUseConcurrent &= instrumentation == null || !instrumentation.isInstrumenting();
- // We can lift this restriction in the future after we've made it possible for test authors
- // to test Looper and MessageQueue without resorting to reflection.
+ if (sIsProcessAllowedToUseConcurrent == null) {
+ // Concurrent mode modifies behavior that is observable via reflection and is commonly
+ // used by tests.
+ // For now, we limit it to system processes to avoid breaking apps and their tests.
+ boolean useConcurrent = UserHandle.isCore(Process.myUid());
- mQuitAllowed = quitAllowed;
- mPtr = nativeInit();
- }
+ // Some platform tests run in system UIDs.
+ // Use this awful heuristic to detect them.
+ if (useConcurrent) {
+ final String processName = Process.myProcessName();
+ if (processName.contains("test") || processName.contains("Test")) {
+ useConcurrent = false;
+ }
+ }
+
+ // We can lift this restriction in the future after we've made it possible for test
+ // authors to test Looper and MessageQueue without resorting to reflection.
- @android.ravenwood.annotation.RavenwoodReplace(blockedBy = ActivityThread.class)
- private static Instrumentation getInstrumentation() {
- final ActivityThread activityThread = ActivityThread.currentActivityThread();
- if (activityThread != null) {
- return activityThread.getInstrumentation();
+ // Holdback study.
+ if (useConcurrent && Flags.messageQueueForceLegacy()) {
+ useConcurrent = false;
+ }
+
+ sIsProcessAllowedToUseConcurrent = useConcurrent;
+ mUseConcurrent = useConcurrent;
+ } else {
+ mUseConcurrent = sIsProcessAllowedToUseConcurrent;
}
- return null;
- }
- private static Instrumentation getInstrumentation$ravenwood() {
- return null; // Instrumentation not supported on Ravenwood yet.
+ mQuitAllowed = quitAllowed;
+ mPtr = nativeInit();
}
@Override
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index e63b6648a9ef..94259d7cf819 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -89,6 +89,8 @@ per-file DdmSyncState.java = sanglardf@google.com, rpaquay@google.com
per-file DdmSyncStageUpdater.java = sanglardf@google.com, rpaquay@google.com
# PerformanceHintManager
+per-file CpuHeadroom*.aidl = file:/ADPF_OWNERS
+per-file GpuHeadroom*.aidl = file:/ADPF_OWNERS
per-file PerformanceHintManager.java = file:/ADPF_OWNERS
per-file WorkDuration.java = file:/ADPF_OWNERS
per-file IHintManager.aidl = file:/ADPF_OWNERS
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 5ac53f1bf39d..3001fbd4fafa 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -4,6 +4,15 @@ container: "system"
# keep-sorted start block=yes newline_separated=yes
flag {
+ # Holdback study for concurrent MessageQueue.
+ # Do not promote beyond trunkfood.
+ namespace: "system_performance"
+ name: "message_queue_force_legacy"
+ description: "Whether to holdback concurrent MessageQueue (force legacy)."
+ bug: "336880969"
+}
+
+flag {
name: "adpf_gpu_report_actual_work_duration"
is_exported: true
namespace: "game"
@@ -222,6 +231,15 @@ flag {
}
flag {
+ name: "message_queue_testability"
+ namespace: "system_performance"
+ is_exported: true
+ description: "Whether MessageQueue implements test APIs."
+ bug: "379472827"
+ is_fixed_read_only: true
+}
+
+flag {
name: "network_time_uses_shared_memory"
namespace: "system_performance"
description: "SystemClock.currentNetworkTimeMillis() reads network time offset from shared memory"
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 55ba4afc9c68..a653e0a493ee 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -58,7 +58,7 @@ flag {
is_fixed_read_only: true
namespace: "permissions"
description: "enable enhanced confirmation incall apis"
- bug: "310220212"
+ bug: "364535720"
}
flag {
@@ -67,7 +67,7 @@ flag {
is_fixed_read_only: true
namespace: "permissions"
description: "enable the blocking of certain app installs during an unknown call"
- bug: "310220212"
+ bug: "364535720"
}
flag {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 23f76299d8c4..d5b525884ac1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10999,6 +10999,25 @@ public final class Settings {
"emergency_gesture_ui_last_started_millis";
/**
+ * Whether double tap the power button gesture is enabled.
+ *
+ * @hide
+ */
+ @Readable
+ public static final String DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED =
+ "double_tap_power_button_gesture_enabled";
+
+ /**
+ * Double tap power button gesture behavior.
+ * 0 = Camera launch
+ * 1 = Wallet launch
+ * @hide
+ */
+ @Readable
+ public static final String DOUBLE_TAP_POWER_BUTTON_GESTURE =
+ "double_tap_power_button_gesture";
+
+ /**
* Whether the camera launch gesture to double tap the power button when the screen is off
* should be disabled.
*
diff --git a/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl b/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
index 8759f72ca08a..eab1c156b6be 100644
--- a/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
+++ b/core/java/android/security/intrusiondetection/IIntrusionDetectionEventTransport.aidl
@@ -15,6 +15,7 @@
*/
package android.security.intrusiondetection;
+
import android.security.intrusiondetection.IntrusionDetectionEvent;
import com.android.internal.infra.AndroidFuture;
@@ -24,18 +25,20 @@ oneway interface IIntrusionDetectionEventTransport {
/**
* Initialize the server side.
*/
- void initialize(in AndroidFuture<int> resultFuture);
+ void initialize(in AndroidFuture<boolean> resultFuture);
/**
- * Send intrusiondetection logging data to the backup destination.
+ * Send intrusiondetection logging data to the transport destination.
* The data is a list of IntrusionDetectionEvent.
* The IntrusionDetectionEvent is an abstract class that represents
- * different type of events.
+ * different types of events.
*/
- void addData(in List<IntrusionDetectionEvent> events, in AndroidFuture<int> resultFuture);
+ void addData(
+ in List<IntrusionDetectionEvent> events,
+ in AndroidFuture<boolean> resultFuture);
/**
* Release the binder to the server.
*/
- void release(in AndroidFuture<int> resultFuture);
+ void release(in AndroidFuture<boolean> resultFuture);
}
diff --git a/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
index 538acf99c9fe..b479ca7a0b6f 100644
--- a/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionEvent.java
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
import android.app.admin.ConnectEvent;
import android.app.admin.DnsEvent;
import android.app.admin.SecurityLog.SecurityEvent;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.security.Flags;
@@ -31,14 +32,36 @@ import java.lang.annotation.RetentionPolicy;
/**
* A class that represents a intrusiondetection event.
+ *
* @hide
*/
+@SystemApi
@FlaggedApi(Flags.FLAG_AFL_API)
public final class IntrusionDetectionEvent implements Parcelable {
private static final String TAG = "IntrusionDetectionEvent";
+ /**
+ * Event type representing a security-related event.
+ * This type is associated with a {@link SecurityEvent} object.
+ *
+ * @see SecurityEvent
+ */
public static final int SECURITY_EVENT = 0;
+
+ /**
+ * Event type representing a network DNS event.
+ * This type is associated with a {@link DnsEvent} object.
+ *
+ * @see DnsEvent
+ */
public static final int NETWORK_EVENT_DNS = 1;
+
+ /**
+ * Event type representing a network connection event.
+ * This type is associated with a {@link ConnectEvent} object.
+ *
+ * @see ConnectEvent
+ */
public static final int NETWORK_EVENT_CONNECT = 2;
/** @hide */
@@ -67,6 +90,12 @@ public final class IntrusionDetectionEvent implements Parcelable {
}
};
+ /**
+ * Creates an IntrusionDetectionEvent object with a
+ * {@link SecurityEvent} object as the event source.
+ *
+ * @param securityEvent The SecurityEvent object.
+ */
public IntrusionDetectionEvent(@NonNull SecurityEvent securityEvent) {
mType = SECURITY_EVENT;
mSecurityEvent = securityEvent;
@@ -74,6 +103,12 @@ public final class IntrusionDetectionEvent implements Parcelable {
mNetworkEventConnect = null;
}
+ /**
+ * Creates an IntrusionDetectionEvent object with a
+ * {@link DnsEvent} object as the event source.
+ *
+ * @param dnsEvent The DnsEvent object.
+ */
public IntrusionDetectionEvent(@NonNull DnsEvent dnsEvent) {
mType = NETWORK_EVENT_DNS;
mNetworkEventDns = dnsEvent;
@@ -81,6 +116,12 @@ public final class IntrusionDetectionEvent implements Parcelable {
mNetworkEventConnect = null;
}
+ /**
+ * Creates an IntrusionDetectionEvent object with a
+ * {@link ConnectEvent} object as the event source.
+ *
+ * @param connectEvent The ConnectEvent object.
+ */
public IntrusionDetectionEvent(@NonNull ConnectEvent connectEvent) {
mType = NETWORK_EVENT_CONNECT;
mNetworkEventConnect = connectEvent;
diff --git a/core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java b/core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java
new file mode 100644
index 000000000000..2e2d0f7f2dd2
--- /dev/null
+++ b/core/java/android/security/intrusiondetection/IntrusionDetectionEventTransport.java
@@ -0,0 +1,145 @@
+/*
+ * 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.security.intrusiondetection;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.annotation.SuppressLint;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.util.CloseGuard;
+
+import android.security.Flags;
+import android.security.intrusiondetection.IntrusionDetectionEvent;
+import android.security.intrusiondetection.IIntrusionDetectionEventTransport;
+
+import com.android.internal.infra.AndroidFuture;
+
+import java.lang.AutoCloseable;
+import java.util.List;
+
+/**
+ * A class that provides a stable API for transporting intrusion detection events
+ * to a transport location, such as a file or a network endpoint.
+ *
+ * This class acts as a bridge between the {@link IIntrusionDetectionEventTransport}
+ * interface and its implementations. It allows system components to add intrusion
+ * detection events ({@link IntrusionDetectionEvent}) to a transport queue,
+ * which will then be delivered to the specified location.
+ *
+ * Usage:
+ * 1. Obtain an instance of {@link IntrusionDetectionEventTransport} using the constructor.
+ * 2. Initialize the transport by calling {@link #initialize()}.
+ * 3. Add events to the transport queue using {@link #addData(List)}.
+ * 4. Release the transport when finished by calling {@link #release()}.
+ *
+ * Key Components:
+ * - {@link IIntrusionDetectionEventTransport}: The underlying AIDL interface
+ * for interacting with transport implementations.
+ * - {@link IntrusionDetectionEvent}: Represents a single event.
+ *
+ * @hide
+ */
+@SystemApi
+@FlaggedApi(Flags.FLAG_AFL_API)
+@SuppressLint("NotCloseable")
+public class IntrusionDetectionEventTransport {
+ IIntrusionDetectionEventTransport mBinderImpl = new TransportImpl();
+
+ /**
+ * Returns the binder interface for this transport.
+ */
+ @NonNull
+ public IBinder getBinder() {
+ return mBinderImpl.asBinder();
+ }
+
+ /**
+ * Initializes the transport.
+ *
+ * @return whether the initialization was successful.
+ */
+ public boolean initialize() {
+ return false;
+ }
+
+ /**
+ * Adds data to the transport.
+ *
+ * @param events the events to add.
+ * @return whether the addition was successful.
+ */
+ public boolean addData(@NonNull List<IntrusionDetectionEvent> events) {
+ return false;
+ }
+
+ /**
+ * Releases the transport.
+ *
+ * The release() method is a callback implemented by the concrete transport
+ * endpoint.
+ * The "SuppressLint" annotation is used to allow the release() method to be
+ * included in the API without requiring the class to implement AutoCloseable.
+ *
+ * @return whether the release was successful.
+ */
+ public boolean release() {
+ return false;
+ }
+
+ /**
+ * Bridge between the actual IIntrusionDetectionEventTransport implementation
+ * and the stable API. If the binder interface needs to change, we use this
+ * layer to translate so that we can decouple those framework-side changes
+ * from the IntrusionDetectionEventTransport implementations.
+ */
+ class TransportImpl extends IIntrusionDetectionEventTransport.Stub {
+ @Override
+ public void initialize(AndroidFuture<Boolean> resultFuture) {
+ try {
+ boolean result = IntrusionDetectionEventTransport.this.initialize();
+ resultFuture.complete(result);
+ } catch (RuntimeException e) {
+ resultFuture.cancel(/* mayInterruptIfRunning */ true);
+ }
+ }
+
+ @Override
+ public void addData(
+ List<IntrusionDetectionEvent> events,
+ AndroidFuture<Boolean> resultFuture) {
+ try {
+ boolean result = IntrusionDetectionEventTransport.this.addData(events);
+ resultFuture.complete(result);
+ } catch (RuntimeException e) {
+ resultFuture.cancel(/* mayInterruptIfRunning */ true);
+ }
+ }
+
+ @Override
+ public void release(AndroidFuture<Boolean> resultFuture) {
+ try {
+ boolean result = IntrusionDetectionEventTransport.this.release();
+ resultFuture.complete(result);
+ } catch (RuntimeException e) {
+ resultFuture.cancel(/* mayInterruptIfRunning */ true);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/core/java/android/service/notification/SystemZenRules.java b/core/java/android/service/notification/SystemZenRules.java
index ebb8569ead49..f11ce1621f93 100644
--- a/core/java/android/service/notification/SystemZenRules.java
+++ b/core/java/android/service/notification/SystemZenRules.java
@@ -122,17 +122,16 @@ public final class SystemZenRules {
@Nullable
public static String getTriggerDescriptionForScheduleTime(Context context,
@NonNull ScheduleInfo schedule) {
- final StringBuilder sb = new StringBuilder();
String daysSummary = getDaysOfWeekShort(context, schedule);
if (daysSummary == null) {
// no use outputting times without dates
return null;
}
- sb.append(daysSummary);
- sb.append(context.getString(R.string.zen_mode_trigger_summary_divider_text));
- sb.append(getTimeSummary(context, schedule));
-
- return sb.toString();
+ return context.getString(
+ R.string.zen_mode_trigger_summary_combined,
+ daysSummary,
+ getTimeSummary(context, schedule)
+ );
}
/**
diff --git a/core/java/android/service/quickaccesswallet/flags.aconfig b/core/java/android/service/quickaccesswallet/flags.aconfig
index 75a93091eec3..7225f27c4555 100644
--- a/core/java/android/service/quickaccesswallet/flags.aconfig
+++ b/core/java/android/service/quickaccesswallet/flags.aconfig
@@ -6,4 +6,11 @@ flag {
namespace: "wallet_integration"
description: "Option to launch the Wallet app on double-tap of the power button"
bug: "378469025"
+}
+
+flag {
+ name: "launch_selected_card_from_qs_tile"
+ namespace: "wallet_integration"
+ description: "When the wallet QS tile is tapped, launch the selected card pending intent instead of the home screen pending intent."
+ bug: "378469025"
} \ No newline at end of file
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 09a78e5ebb4e..c9d560c3424b 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -20,6 +20,7 @@ import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE;
import static android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS;
import static android.hardware.flags.Flags.FLAG_OVERLAYPROPERTIES_CLASS_API;
+import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_GET_SUPPORTED_REFRESH_RATES;
import static com.android.server.display.feature.flags.Flags.FLAG_HIGHEST_HDR_SDR_RATIO_API;
import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_HAS_ARR_SUPPORT;
import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE;
@@ -63,6 +64,7 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -1207,17 +1209,36 @@ public final class Display {
/**
* Get the supported refresh rates of this display in frames per second.
- * <p>
- * This method only returns refresh rates for the display's default modes. For more options, use
- * {@link #getSupportedModes()}.
*
- * @deprecated use {@link #getSupportedModes()} instead
+ * <ul>
+ * <li> Android version {@link Build.VERSION_CODES#BAKLAVA} and above:
+ * returns display supported render rates.
+ * <li> Android version {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} and below:
+ * This method only returns refresh rates for the display's default modes. For more options,
+ * use {@link #getSupportedModes()}.
+ * </ul>
*/
- @Deprecated
- public float[] getSupportedRefreshRates() {
+ @FlaggedApi(FLAG_ENABLE_GET_SUPPORTED_REFRESH_RATES)
+ public @NonNull float[] getSupportedRefreshRates() {
synchronized (mLock) {
updateDisplayInfoLocked();
- return mDisplayInfo.getDefaultRefreshRates();
+ final float[] refreshRates = mDisplayInfo.getDefaultRefreshRates();
+ Objects.requireNonNull(refreshRates);
+ return refreshRates;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @TestApi
+ @SuppressLint({"UnflaggedApi"}) // Usage in the CTS to test backward compatibility.
+ public @NonNull float[] getSupportedRefreshRatesLegacy() {
+ synchronized (mLock) {
+ updateDisplayInfoLocked();
+ final float[] refreshRates = mDisplayInfo.getDefaultRefreshRatesLegacy();
+ Objects.requireNonNull(refreshRates);
+ return refreshRates;
}
}
@@ -2449,6 +2470,8 @@ public final class Display {
* constrained by the system.
* @hide
*/
+ @SuppressWarnings("UnflaggedApi") // For testing only
+ @TestApi
public float getVsyncRate() {
return mVsyncRate;
}
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 4ff04d5c1fa6..8b6458a54c43 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -210,6 +210,11 @@ public final class DisplayInfo implements Parcelable {
public FrameRateCategoryRate frameRateCategoryRate;
/**
+ * All the refresh rates supported in the active mode.
+ */
+ public float[] supportedRefreshRates = new float[0];
+
+ /**
* The default display mode.
*/
public int defaultModeId;
@@ -449,6 +454,7 @@ public final class DisplayInfo implements Parcelable {
&& modeId == other.modeId
&& hasArrSupport == other.hasArrSupport
&& Objects.equals(frameRateCategoryRate, other.frameRateCategoryRate)
+ && Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
&& defaultModeId == other.defaultModeId
&& userPreferredModeId == other.userPreferredModeId
&& Arrays.equals(supportedModes, other.supportedModes)
@@ -512,6 +518,8 @@ public final class DisplayInfo implements Parcelable {
renderFrameRate = other.renderFrameRate;
hasArrSupport = other.hasArrSupport;
frameRateCategoryRate = other.frameRateCategoryRate;
+ supportedRefreshRates = Arrays.copyOf(
+ other.supportedRefreshRates, other.supportedRefreshRates.length);
defaultModeId = other.defaultModeId;
userPreferredModeId = other.userPreferredModeId;
supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
@@ -571,6 +579,11 @@ public final class DisplayInfo implements Parcelable {
hasArrSupport = source.readBoolean();
frameRateCategoryRate = source.readParcelable(null,
android.view.FrameRateCategoryRate.class);
+ int numOfSupportedRefreshRates = source.readInt();
+ supportedRefreshRates = new float[numOfSupportedRefreshRates];
+ for (int i = 0; i < numOfSupportedRefreshRates; i++) {
+ supportedRefreshRates[i] = source.readFloat();
+ }
defaultModeId = source.readInt();
userPreferredModeId = source.readInt();
int nModes = source.readInt();
@@ -646,6 +659,10 @@ public final class DisplayInfo implements Parcelable {
dest.writeFloat(renderFrameRate);
dest.writeBoolean(hasArrSupport);
dest.writeParcelable(frameRateCategoryRate, flags);
+ dest.writeInt(supportedRefreshRates.length);
+ for (float supportedRefreshRate : supportedRefreshRates) {
+ dest.writeFloat(supportedRefreshRate);
+ }
dest.writeInt(defaultModeId);
dest.writeInt(userPreferredModeId);
dest.writeInt(supportedModes.length);
@@ -750,9 +767,19 @@ public final class DisplayInfo implements Parcelable {
}
/**
- * Returns the list of supported refresh rates in the default mode.
+ * Returns the list of supported refresh rates in the active mode.
*/
public float[] getDefaultRefreshRates() {
+ if (supportedRefreshRates.length == 0) {
+ return getDefaultRefreshRatesLegacy();
+ }
+ return Arrays.copyOf(supportedRefreshRates, supportedRefreshRates.length);
+ }
+
+ /**
+ * Returns the list of supported refresh rates in the default mode.
+ */
+ public float[] getDefaultRefreshRatesLegacy() {
Display.Mode[] modes = appsSupportedModes;
ArraySet<Float> rates = new ArraySet<>();
Display.Mode defaultMode = getDefaultMode();
@@ -898,6 +925,8 @@ public final class DisplayInfo implements Parcelable {
sb.append(hasArrSupport);
sb.append(", frameRateCategoryRate ");
sb.append(frameRateCategoryRate);
+ sb.append(", supportedRefreshRates ");
+ sb.append(Arrays.toString(supportedRefreshRates));
sb.append(", defaultMode ");
sb.append(defaultModeId);
sb.append(", userPreferredModeId ");
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 58ef5efe846f..6cd4a4033adf 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -260,6 +260,15 @@ public final class InputWindowHandle {
touchableRegionSurfaceControl = new WeakReference<>(bounds);
}
+ /**
+ * Resize the window touchable region.
+ * @param rect new touchable region rectangle.
+ */
+ public void setTouchableRegion(Rect rect) {
+ touchableRegion.set(rect);
+ }
+
+
public void setWindowToken(IBinder iwindow) {
windowToken = iwindow;
}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 68674dd402b4..dd9a95e58bd1 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1932,6 +1932,7 @@ public final class SurfaceControl implements Parcelable {
public float renderFrameRate;
public boolean hasArrSupport;
public FrameRateCategoryRate frameRateCategoryRate;
+ public float[] supportedRefreshRates;
public int[] supportedColorModes;
public int activeColorMode;
@@ -1951,6 +1952,7 @@ public final class SurfaceControl implements Parcelable {
+ ", renderFrameRate=" + renderFrameRate
+ ", hasArrSupport=" + hasArrSupport
+ ", frameRateCategoryRate=" + frameRateCategoryRate
+ + ", supportedRefreshRates=" + Arrays.toString(supportedRefreshRates)
+ ", supportedColorModes=" + Arrays.toString(supportedColorModes)
+ ", activeColorMode=" + activeColorMode
+ ", hdrCapabilities=" + hdrCapabilities
@@ -1972,14 +1974,15 @@ public final class SurfaceControl implements Parcelable {
&& Objects.equals(hdrCapabilities, that.hdrCapabilities)
&& preferredBootDisplayMode == that.preferredBootDisplayMode
&& hasArrSupport == that.hasArrSupport
- && Objects.equals(frameRateCategoryRate, that.frameRateCategoryRate);
+ && Objects.equals(frameRateCategoryRate, that.frameRateCategoryRate)
+ && Arrays.equals(supportedRefreshRates, that.supportedRefreshRates);
}
@Override
public int hashCode() {
return Objects.hash(Arrays.hashCode(supportedDisplayModes), activeDisplayModeId,
renderFrameRate, activeColorMode, hdrCapabilities, hasArrSupport,
- frameRateCategoryRate);
+ frameRateCategoryRate, Arrays.hashCode(supportedRefreshRates));
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 072a835eb664..b6e114b3a3ca 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -8876,11 +8876,6 @@ public final class ViewRootImpl implements ViewParent,
SyntheticTouchNavigationHandler() {
super(true);
- int gestureDetectorVelocityStrategy =
- android.companion.virtual.flags.Flags
- .impulseVelocityStrategyForTouchNavigation()
- ? VelocityTracker.VELOCITY_TRACKER_STRATEGY_IMPULSE
- : VelocityTracker.VELOCITY_TRACKER_STRATEGY_DEFAULT;
mGestureDetector = new GestureDetector(mContext,
new GestureDetector.OnGestureListener() {
@Override
@@ -8920,7 +8915,7 @@ public final class ViewRootImpl implements ViewParent,
}
},
/* handler= */ null,
- gestureDetectorVelocityStrategy);
+ VelocityTracker.VELOCITY_TRACKER_STRATEGY_IMPULSE);
}
public void process(MotionEvent event) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index b4b0687eb498..1e8cad61381c 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1426,8 +1426,9 @@ public interface WindowManager extends ViewManager {
"android.window.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE";
/**
- * Activity-level {@link android.content.pm.PackageManager.Property PackageManager.Property}
- * that specifies whether this activity can declare or request
+ * Application or Activity level
+ * {@link android.content.pm.PackageManager.Property PackageManager.Property}
+ * that specifies whether this package or activity can declare or request
* {@link android.R.attr#screenOrientation fixed orientation},
* {@link android.R.attr#minAspectRatio max aspect ratio},
* {@link android.R.attr#maxAspectRatio min aspect ratio}
@@ -1438,6 +1439,13 @@ public interface WindowManager extends ViewManager {
*
* <p><b>Syntax:</b>
* <pre>
+ * &lt;application&gt;
+ * &lt;property
+ * android:name="android.window.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE"
+ * android:value="false"/&gt;
+ * &lt;/application&gt;
+ * </pre>or
+ * <pre>
* &lt;activity&gt;
* &lt;property
* android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY"
@@ -1446,7 +1454,7 @@ public interface WindowManager extends ViewManager {
* </pre>
* @hide
*/
- // TODO(b/357141415): Make this public API.
+ // TODO(b/357141415): Remove this from sdk 37
String PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY =
"android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY";
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 0204517e869a..df0c5a34e992 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -6551,15 +6551,23 @@ public class AccessibilityNodeInfo implements Parcelable {
/**
* Range type: indeterminate.
*
+ * When using this type, the {@code min}, {@code max}, and {@code current} values used to
+ * construct an instance may be ignored.
+ *
+ * @see #INDETERMINATE
+ */
+ @FlaggedApi(Flags.FLAG_INDETERMINATE_RANGE_INFO)
+ public static final int RANGE_TYPE_INDETERMINATE = 3;
+
+ /**
* A {@link RangeInfo} type used to represent a node which may typically expose range
* information but is presently in an indeterminate state, such as a {@link
* android.widget.ProgressBar} representing a loading operation of unknown duration.
- * When using this type, the {@code min}, {@code max}, and {@code current} values used to
- * construct an instance may be ignored. It is recommended to use {@code Float.NaN} for
- * these values.
*/
+ @NonNull
@FlaggedApi(Flags.FLAG_INDETERMINATE_RANGE_INFO)
- public static final int RANGE_TYPE_INDETERMINATE = 3;
+ public static final RangeInfo INDETERMINATE = new RangeInfo(RANGE_TYPE_INDETERMINATE, 0.0f,
+ 0.0f, 0.0f);
private int mType;
private float mMin;
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 80d39d1f9a1c..595eb260f998 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -9333,7 +9333,11 @@ public class RemoteViews implements Parcelable, Filter {
Set<Integer> bitmapIdSet = getBitmapIdsUsedByActions(new HashSet<>());
int result = 0;
for (int bitmapId: bitmapIdSet) {
- result += mBitmapCache.getBitmapForId(bitmapId).getAllocationByteCount();
+ Bitmap currentBitmap = mBitmapCache.getBitmapForId(bitmapId);
+ if (currentBitmap == null) {
+ continue;
+ }
+ result += currentBitmap.getAllocationByteCount();
}
return result;
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
index 15adc80add01..6e76d8d345b2 100644
--- a/core/java/android/window/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -19,6 +19,8 @@ import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded;
import static android.window.ConfigurationHelper.isDifferentDisplay;
import static android.window.ConfigurationHelper.shouldUpdateResources;
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
import android.annotation.AnyThread;
import android.annotation.MainThread;
import android.annotation.NonNull;
@@ -104,7 +106,7 @@ public class WindowTokenClient extends Binder {
* @param newConfig the updated {@link Configuration}
* @param newDisplayId the updated {@link android.view.Display} ID
*/
- @VisibleForTesting
+ @VisibleForTesting(visibility = PACKAGE)
@MainThread
public void onConfigurationChanged(Configuration newConfig, int newDisplayId) {
onConfigurationChanged(newConfig, newDisplayId, true /* shouldReportConfigChange */);
@@ -113,7 +115,7 @@ public class WindowTokenClient extends Binder {
/**
* Posts an {@link #onConfigurationChanged} to the main thread.
*/
- @VisibleForTesting
+ @VisibleForTesting(visibility = PACKAGE)
public void postOnConfigurationChanged(@NonNull Configuration newConfig, int newDisplayId) {
mHandler.post(PooledLambda.obtainRunnable(this::onConfigurationChanged, newConfig,
newDisplayId, true /* shouldReportConfigChange */).recycleOnUse());
@@ -232,7 +234,7 @@ public class WindowTokenClient extends Binder {
/**
* Called when the attached window is removed from the display.
*/
- @VisibleForTesting
+ @VisibleForTesting(visibility = PACKAGE)
@MainThread
public void onWindowTokenRemoved() {
final Context context = mContextRef.get();
diff --git a/core/java/android/window/WindowTokenClientController.java b/core/java/android/window/WindowTokenClientController.java
index abf7bb15b3d8..fa345956ec4d 100644
--- a/core/java/android/window/WindowTokenClientController.java
+++ b/core/java/android/window/WindowTokenClientController.java
@@ -28,7 +28,7 @@ import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
-import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.Log;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
@@ -50,9 +50,9 @@ public class WindowTokenClientController {
private final IApplicationThread mAppThread = ActivityThread.currentActivityThread()
.getApplicationThread();
- /** Mapping from a client defined token to the {@link WindowTokenClient} it represents. */
+ /** Attached {@link WindowTokenClient}. */
@GuardedBy("mLock")
- private final ArrayMap<IBinder, WindowTokenClient> mWindowTokenClientMap = new ArrayMap<>();
+ private final ArraySet<WindowTokenClient> mWindowTokenClients = new ArraySet<>();
/** Gets the singleton controller. */
@NonNull
@@ -85,11 +85,15 @@ public class WindowTokenClientController {
/** Gets the {@link WindowContext} instance for the token. */
@Nullable
public Context getWindowContext(@NonNull IBinder clientToken) {
- final WindowTokenClient windowTokenClient;
+ if (!(clientToken instanceof WindowTokenClient windowTokenClient)) {
+ return null;
+ }
synchronized (mLock) {
- windowTokenClient = mWindowTokenClientMap.get(clientToken);
+ if (!mWindowTokenClients.contains(windowTokenClient)) {
+ return null;
+ }
}
- return windowTokenClient != null ? windowTokenClient.getContext() : null;
+ return windowTokenClient.getContext();
}
/**
@@ -126,8 +130,14 @@ public class WindowTokenClientController {
*/
public boolean attachToDisplayContent(@NonNull WindowTokenClient client, int displayId) {
final IWindowManager wms = getWindowManagerService();
- // #createSystemUiContext may call this method before WindowManagerService is initialized.
if (wms == null) {
+ // #createSystemUiContext may call this method before WindowManagerService is
+ // initialized.
+ // Regardless of whether or not it is ready, keep track of the token so that when WMS
+ // is initialized later, the SystemUiContext will start reporting from
+ // DisplayContent#registerSystemUiContext, and WindowTokenClientController can report
+ // the Configuration to the correct client.
+ recordWindowContextToken(client);
return false;
}
final WindowContextInfo info;
@@ -170,12 +180,18 @@ public class WindowTokenClientController {
/** Detaches a {@link WindowTokenClient} from associated WindowContainer if there's one. */
public void detachIfNeeded(@NonNull WindowTokenClient client) {
synchronized (mLock) {
- if (mWindowTokenClientMap.remove(client) == null) {
+ if (!mWindowTokenClients.remove(client)) {
return;
}
}
+ final IWindowManager wms = getWindowManagerService();
+ if (wms == null) {
+ // #createSystemUiContext may call this method before WindowManagerService is
+ // initialized. If it is GC'ed before WMS is initialized, skip calling into WMS.
+ return;
+ }
try {
- getWindowManagerService().detachWindowContext(client);
+ wms.detachWindowContext(client);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -183,9 +199,7 @@ public class WindowTokenClientController {
private void onWindowContextTokenAttached(@NonNull WindowTokenClient client,
@NonNull WindowContextInfo info, boolean shouldReportConfigChange) {
- synchronized (mLock) {
- mWindowTokenClientMap.put(client, client);
- }
+ recordWindowContextToken(client);
if (shouldReportConfigChange) {
// Should trigger an #onConfigurationChanged callback to the WindowContext. Post the
// dispatch in the next loop to prevent the callback from being dispatched before
@@ -199,10 +213,16 @@ public class WindowTokenClientController {
}
}
+ private void recordWindowContextToken(@NonNull WindowTokenClient client) {
+ synchronized (mLock) {
+ mWindowTokenClients.add(client);
+ }
+ }
+
/** Called when receives {@link WindowContextInfoChangeItem}. */
public void onWindowContextInfoChanged(@NonNull IBinder clientToken,
@NonNull WindowContextInfo info) {
- final WindowTokenClient windowTokenClient = getWindowTokenClient(clientToken);
+ final WindowTokenClient windowTokenClient = getWindowTokenClientIfAttached(clientToken);
if (windowTokenClient != null) {
windowTokenClient.onConfigurationChanged(info.getConfiguration(), info.getDisplayId());
}
@@ -210,20 +230,23 @@ public class WindowTokenClientController {
/** Called when receives {@link WindowContextWindowRemovalItem}. */
public void onWindowContextWindowRemoved(@NonNull IBinder clientToken) {
- final WindowTokenClient windowTokenClient = getWindowTokenClient(clientToken);
+ final WindowTokenClient windowTokenClient = getWindowTokenClientIfAttached(clientToken);
if (windowTokenClient != null) {
windowTokenClient.onWindowTokenRemoved();
}
}
@Nullable
- private WindowTokenClient getWindowTokenClient(@NonNull IBinder clientToken) {
- final WindowTokenClient windowTokenClient;
- synchronized (mLock) {
- windowTokenClient = mWindowTokenClientMap.get(clientToken);
+ private WindowTokenClient getWindowTokenClientIfAttached(@NonNull IBinder clientToken) {
+ if (!(clientToken instanceof WindowTokenClient windowTokenClient)) {
+ Log.e(TAG, "getWindowTokenClient failed for non-window token " + clientToken);
+ return null;
}
- if (windowTokenClient == null) {
- Log.w(TAG, "Can't find attached WindowTokenClient for " + clientToken);
+ synchronized (mLock) {
+ if (!mWindowTokenClients.contains(windowTokenClient)) {
+ Log.w(TAG, "Can't find attached WindowTokenClient for " + clientToken);
+ return null;
+ }
}
return windowTokenClient;
}
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index eebdeadcdeb2..8019e6791cf1 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -242,6 +242,13 @@ flag {
}
flag {
+ name: "enable_desktop_windowing_app_handle_education_integration"
+ namespace: "lse_desktop_experience"
+ description: "Enables desktop windowing app handle education and integrates new APIs"
+ bug: "380272815"
+}
+
+flag {
name: "enable_desktop_windowing_transitions"
namespace: "lse_desktop_experience"
description: "Enables desktop windowing transition & motion polish changes"
@@ -256,6 +263,16 @@ flag {
}
flag {
+ name: "enable_desktop_windowing_enter_transition_bugfix"
+ namespace: "lse_desktop_experience"
+ description: "Enables enter desktop windowing transition & motion polish changes"
+ bug: "380224875"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "enable_desktop_windowing_exit_transitions"
namespace: "lse_desktop_experience"
description: "Enables exit desktop windowing transition & motion polish changes"
@@ -263,6 +280,16 @@ flag {
}
flag {
+ name: "enable_desktop_windowing_exit_transitions_bugfix"
+ namespace: "lse_desktop_experience"
+ description: "Enables exit desktop windowing transition & motion polish changes"
+ bug: "380224768"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "enable_compat_ui_visibility_status"
namespace: "lse_desktop_experience"
description: "Enables the tracking of the status for compat ui elements."
@@ -346,6 +373,16 @@ flag {
}
flag {
+ name: "enable_desktop_app_launch_alttab_transitions_bugfix"
+ namespace: "lse_desktop_experience"
+ description: "Enables custom transitions for alt-tab app launches in Desktop Mode."
+ bug: "380225486"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "enable_desktop_app_launch_transitions"
namespace: "lse_desktop_experience"
description: "Enables custom transitions for app launches in Desktop Mode."
@@ -353,6 +390,16 @@ flag {
}
flag {
+ name: "enable_desktop_app_launch_transitions_bugfix"
+ namespace: "lse_desktop_experience"
+ description: "Enables custom transitions for app launches in Desktop Mode."
+ bug: "380224832"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "enable_desktop_system_dialogs_transitions"
namespace: "lse_desktop_experience"
description: "Enables custom transitions for system dialogs in Desktop Mode."
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 86bbeb827703..ebbe4830009c 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -441,3 +441,11 @@ flag {
description: "Enable Predictive Back Animation for 3-button-nav"
bug: "373544911"
}
+
+flag {
+ name: "predictive_back_default_enable_sdk_36"
+ namespace: "systemui"
+ description: "Enable Predictive Back by default with targetSdk>=36"
+ is_fixed_read_only: true
+ bug: "376407910"
+}
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
index 8a6e6be1abbf..5fc1276dd9f9 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
@@ -2377,6 +2377,7 @@ public class ParsingPackageUtils {
* Flags are separated by type and by default value. They are sorted alphabetically within each
* section.
*/
+ @SuppressWarnings("AndroidFrameworkCompatChange")
private void parseBaseAppBasicFlags(ParsingPackage pkg, TypedArray sa) {
int targetSdk = pkg.getTargetSdkVersion();
//@formatter:off
@@ -2414,12 +2415,20 @@ public class ParsingPackageUtils {
.setResetEnabledSettingsOnAppDataCleared(bool(false,
R.styleable.AndroidManifestApplication_resetEnabledSettingsOnAppDataCleared,
sa))
- .setOnBackInvokedCallbackEnabled(bool(false, R.styleable.AndroidManifestApplication_enableOnBackInvokedCallback, sa))
// targetSdkVersion gated
.setAllowAudioPlaybackCapture(bool(targetSdk >= Build.VERSION_CODES.Q, R.styleable.AndroidManifestApplication_allowAudioPlaybackCapture, sa))
.setHardwareAccelerated(bool(targetSdk >= Build.VERSION_CODES.ICE_CREAM_SANDWICH, R.styleable.AndroidManifestApplication_hardwareAccelerated, sa))
.setRequestLegacyExternalStorage(bool(targetSdk < Build.VERSION_CODES.Q, R.styleable.AndroidManifestApplication_requestLegacyExternalStorage, sa))
.setCleartextTrafficAllowed(bool(targetSdk < Build.VERSION_CODES.P, R.styleable.AndroidManifestApplication_usesCleartextTraffic, sa))
+ // CompatChange.isChangeEnabled() can't be used here because this is called during
+ // PackageManagerService initialization. PlatformCompat can't be used because this
+ // code is not guaranteed to be called from the system_server process. Therefore
+ // accessing Build.VERSION_CODES directly and suppressing
+ // AndroidFrameworkCompatChange warning
+ .setOnBackInvokedCallbackEnabled(bool(
+ com.android.window.flags.Flags.predictiveBackDefaultEnableSdk36()
+ && targetSdk > Build.VERSION_CODES.VANILLA_ICE_CREAM,
+ R.styleable.AndroidManifestApplication_enableOnBackInvokedCallback, sa))
// Ints Default 0
.setUiOptions(anInt(R.styleable.AndroidManifestApplication_uiOptions, sa))
// Ints
diff --git a/core/java/com/android/internal/vibrator/persistence/SerializedCompositionPrimitive.java b/core/java/com/android/internal/vibrator/persistence/SerializedCompositionPrimitive.java
index 862f7cb1d476..5eedec6a63e4 100644
--- a/core/java/com/android/internal/vibrator/persistence/SerializedCompositionPrimitive.java
+++ b/core/java/com/android/internal/vibrator/persistence/SerializedCompositionPrimitive.java
@@ -17,6 +17,7 @@
package com.android.internal.vibrator.persistence;
import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_DELAY_MS;
+import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_DELAY_TYPE;
import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_NAME;
import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_SCALE;
import static com.android.internal.vibrator.persistence.XmlConstants.NAMESPACE;
@@ -25,9 +26,11 @@ import static com.android.internal.vibrator.persistence.XmlConstants.TAG_PRIMITI
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.VibrationEffect;
+import android.os.vibrator.Flags;
import android.os.vibrator.PrimitiveSegment;
import com.android.internal.vibrator.persistence.SerializedComposedEffect.SerializedSegment;
+import com.android.internal.vibrator.persistence.XmlConstants.PrimitiveDelayType;
import com.android.internal.vibrator.persistence.XmlConstants.PrimitiveEffectName;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -46,17 +49,26 @@ final class SerializedCompositionPrimitive implements SerializedSegment {
private final PrimitiveEffectName mPrimitiveName;
private final float mPrimitiveScale;
private final int mPrimitiveDelayMs;
+ @Nullable
+ private final PrimitiveDelayType mDelayType;
- SerializedCompositionPrimitive(PrimitiveEffectName primitiveName, float scale, int delayMs) {
+ SerializedCompositionPrimitive(PrimitiveEffectName primitiveName, float scale, int delayMs,
+ @Nullable PrimitiveDelayType delayType) {
mPrimitiveName = primitiveName;
mPrimitiveScale = scale;
mPrimitiveDelayMs = delayMs;
+ mDelayType = delayType;
}
@Override
public void deserializeIntoComposition(@NonNull VibrationEffect.Composition composition) {
- composition.addPrimitive(mPrimitiveName.getPrimitiveId(), mPrimitiveScale,
- mPrimitiveDelayMs);
+ if (Flags.primitiveCompositionAbsoluteDelay() && mDelayType != null) {
+ composition.addPrimitive(mPrimitiveName.getPrimitiveId(), mPrimitiveScale,
+ mPrimitiveDelayMs, mDelayType.getDelayType());
+ } else {
+ composition.addPrimitive(mPrimitiveName.getPrimitiveId(), mPrimitiveScale,
+ mPrimitiveDelayMs);
+ }
}
@Override
@@ -72,6 +84,12 @@ final class SerializedCompositionPrimitive implements SerializedSegment {
serializer.attributeInt(NAMESPACE, ATTRIBUTE_DELAY_MS, mPrimitiveDelayMs);
}
+ if (Flags.primitiveCompositionAbsoluteDelay() && mDelayType != null) {
+ if (mDelayType.getDelayType() != PrimitiveSegment.DEFAULT_DELAY_TYPE) {
+ serializer.attribute(NAMESPACE, ATTRIBUTE_DELAY_TYPE, mDelayType.toString());
+ }
+ }
+
serializer.endTag(NAMESPACE, TAG_PRIMITIVE_EFFECT);
}
@@ -81,6 +99,7 @@ final class SerializedCompositionPrimitive implements SerializedSegment {
+ "name=" + mPrimitiveName
+ ", scale=" + mPrimitiveScale
+ ", delayMs=" + mPrimitiveDelayMs
+ + ", delayType=" + mDelayType
+ '}';
}
@@ -91,8 +110,14 @@ final class SerializedCompositionPrimitive implements SerializedSegment {
static SerializedCompositionPrimitive parseNext(@NonNull TypedXmlPullParser parser)
throws XmlParserException, IOException {
XmlValidator.checkStartTag(parser, TAG_PRIMITIVE_EFFECT);
- XmlValidator.checkTagHasNoUnexpectedAttributes(parser,
- ATTRIBUTE_NAME, ATTRIBUTE_DELAY_MS, ATTRIBUTE_SCALE);
+
+ if (Flags.primitiveCompositionAbsoluteDelay()) {
+ XmlValidator.checkTagHasNoUnexpectedAttributes(parser,
+ ATTRIBUTE_NAME, ATTRIBUTE_DELAY_MS, ATTRIBUTE_SCALE, ATTRIBUTE_DELAY_TYPE);
+ } else {
+ XmlValidator.checkTagHasNoUnexpectedAttributes(parser,
+ ATTRIBUTE_NAME, ATTRIBUTE_DELAY_MS, ATTRIBUTE_SCALE);
+ }
PrimitiveEffectName primitiveName = parsePrimitiveName(
parser.getAttributeValue(NAMESPACE, ATTRIBUTE_NAME));
@@ -100,11 +125,13 @@ final class SerializedCompositionPrimitive implements SerializedSegment {
parser, ATTRIBUTE_SCALE, 0, 1, PrimitiveSegment.DEFAULT_SCALE);
int delayMs = XmlReader.readAttributeIntNonNegative(
parser, ATTRIBUTE_DELAY_MS, PrimitiveSegment.DEFAULT_DELAY_MILLIS);
+ PrimitiveDelayType delayType = parseDelayType(
+ parser.getAttributeValue(NAMESPACE, ATTRIBUTE_DELAY_TYPE));
// Consume tag
XmlReader.readEndTag(parser);
- return new SerializedCompositionPrimitive(primitiveName, scale, delayMs);
+ return new SerializedCompositionPrimitive(primitiveName, scale, delayMs, delayType);
}
@NonNull
@@ -119,5 +146,21 @@ final class SerializedCompositionPrimitive implements SerializedSegment {
}
return effectName;
}
+
+ @Nullable
+ private static PrimitiveDelayType parseDelayType(@Nullable String name)
+ throws XmlParserException {
+ if (name == null) {
+ return null;
+ }
+ if (!Flags.primitiveCompositionAbsoluteDelay()) {
+ throw new XmlParserException("Unexpected primitive delay type " + name);
+ }
+ PrimitiveDelayType delayType = PrimitiveDelayType.findByName(name);
+ if (delayType == null) {
+ throw new XmlParserException("Unexpected primitive delay type " + name);
+ }
+ return delayType;
+ }
}
}
diff --git a/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java b/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java
index d74a23d47f4a..cb834a5eac7e 100644
--- a/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java
+++ b/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java
@@ -27,6 +27,7 @@ import android.os.vibrator.VibrationEffectSegment;
import com.android.internal.vibrator.persistence.SerializedComposedEffect.SerializedSegment;
import com.android.internal.vibrator.persistence.XmlConstants.PredefinedEffectName;
+import com.android.internal.vibrator.persistence.XmlConstants.PrimitiveDelayType;
import com.android.internal.vibrator.persistence.XmlConstants.PrimitiveEffectName;
import java.util.List;
@@ -170,8 +171,20 @@ public final class VibrationEffectXmlSerializer {
XmlValidator.checkSerializerCondition(primitiveName != null,
"Unsupported primitive effect id %s", primitive.getPrimitiveId());
+ PrimitiveDelayType delayType = null;
+
+ if (Flags.primitiveCompositionAbsoluteDelay()) {
+ delayType = PrimitiveDelayType.findByType(primitive.getDelayType());
+ XmlValidator.checkSerializerCondition(delayType != null,
+ "Unsupported primitive delay type %s", primitive.getDelayType());
+ } else {
+ XmlValidator.checkSerializerCondition(
+ primitive.getDelayType() == PrimitiveSegment.DEFAULT_DELAY_TYPE,
+ "Unsupported primitive delay type %s", primitive.getDelayType());
+ }
+
return new SerializedCompositionPrimitive(
- primitiveName, primitive.getScale(), primitive.getDelay());
+ primitiveName, primitive.getScale(), primitive.getDelay(), delayType);
}
private static int toAmplitudeInt(float amplitude) {
diff --git a/core/java/com/android/internal/vibrator/persistence/XmlConstants.java b/core/java/com/android/internal/vibrator/persistence/XmlConstants.java
index 2a55d999bc0f..4122215a2b04 100644
--- a/core/java/com/android/internal/vibrator/persistence/XmlConstants.java
+++ b/core/java/com/android/internal/vibrator/persistence/XmlConstants.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.VibrationEffect;
+import android.os.VibrationEffect.Composition.DelayType;
import android.os.VibrationEffect.Composition.PrimitiveType;
import java.lang.annotation.Retention;
@@ -51,6 +52,7 @@ public final class XmlConstants {
public static final String ATTRIBUTE_AMPLITUDE = "amplitude";
public static final String ATTRIBUTE_SCALE = "scale";
public static final String ATTRIBUTE_DELAY_MS = "delayMs";
+ public static final String ATTRIBUTE_DELAY_TYPE = "delayType";
public static final String VALUE_AMPLITUDE_DEFAULT = "default";
@@ -87,7 +89,7 @@ public final class XmlConstants {
/**
* Return the {@link PrimitiveEffectName} that represents given primitive id, or null if
- * none of the available names maps to the given id.
+ * none of the available names map to the given id.
*/
@Nullable
public static PrimitiveEffectName findById(int primitiveId) {
@@ -200,4 +202,53 @@ public final class XmlConstants {
return name().toLowerCase(Locale.ROOT);
}
}
+
+ /** Represent supported values for attribute delay type in {@link #TAG_PRIMITIVE_EFFECT} */
+ public enum PrimitiveDelayType {
+ PAUSE(VibrationEffect.Composition.DELAY_TYPE_PAUSE),
+ RELATIVE_START_OFFSET(VibrationEffect.Composition.DELAY_TYPE_RELATIVE_START_OFFSET);
+
+ @DelayType private final int mDelayType;
+
+ PrimitiveDelayType(@DelayType int type) {
+ mDelayType = type;
+ }
+
+ /**
+ * Return the {@link PrimitiveEffectName} that represents given primitive id, or null if
+ * none of the available names maps to the given id.
+ */
+ @Nullable
+ public static PrimitiveDelayType findByType(int delayType) {
+ for (PrimitiveDelayType type : PrimitiveDelayType.values()) {
+ if (type.mDelayType == delayType) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return the {@link PrimitiveEffectName} that represents given primitive name, or null if
+ * none of the available names maps to the given name.
+ */
+ @Nullable
+ public static PrimitiveDelayType findByName(@NonNull String delayType) {
+ try {
+ return PrimitiveDelayType.valueOf(delayType.toUpperCase(Locale.ROOT));
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ @DelayType
+ public int getDelayType() {
+ return mDelayType;
+ }
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.ROOT);
+ }
+ }
}
diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp
index ded1a9949ef8..1e7bfe32ba79 100644
--- a/core/jni/android_content_res_ApkAssets.cpp
+++ b/core/jni/android_content_res_ApkAssets.cpp
@@ -36,6 +36,8 @@ using ::android::base::unique_fd;
namespace android {
+static constexpr bool kLogWeakReachableDeletedAssets = false;
+
static struct overlayableinfo_offsets_t {
jclass classObject;
jmethodID constructor;
@@ -97,7 +99,7 @@ static void DeleteGuardedApkAssets(Guarded<AssetManager2::ApkAssetsPtr>& apk_ass
if (useCount > 1) {
ALOGW("ApkAssets: Deleting an object '%s' with %d > 1 strong and %d weak references",
(*assets)->GetDebugName().c_str(), int(useCount), int(weakCount));
- } else if (weakCount > 0) {
+ } else if constexpr (kLogWeakReachableDeletedAssets) if (weakCount > 0) {
ALOGW("ApkAssets: Deleting an ApkAssets object '%s' with %d weak references",
(*assets)->GetDebugName().c_str(), int(weakCount));
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 68e642086636..0c243d1dc185 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -119,6 +119,7 @@ static struct {
jfieldID renderFrameRate;
jfieldID hasArrSupport;
jfieldID frameRateCategoryRate;
+ jfieldID supportedRefreshRates;
jfieldID supportedColorModes;
jfieldID activeColorMode;
jfieldID hdrCapabilities;
@@ -1508,6 +1509,21 @@ static jobject nativeGetDynamicDisplayInfo(JNIEnv* env, jclass clazz, jlong disp
env->SetBooleanField(object, gDynamicDisplayInfoClassInfo.hasArrSupport, info.hasArrSupport);
env->SetObjectField(object, gDynamicDisplayInfoClassInfo.frameRateCategoryRate,
convertFrameRateCategoryRateToJavaObject(env, info.frameRateCategoryRate));
+
+ jfloatArray supportedRefreshRatesArray = env->NewFloatArray(info.supportedRefreshRates.size());
+ if (supportedRefreshRatesArray == NULL) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ return NULL;
+ }
+ jfloat* supportedRefreshRatesArrayValues =
+ env->GetFloatArrayElements(supportedRefreshRatesArray, 0);
+ for (size_t i = 0; i < info.supportedRefreshRates.size(); i++) {
+ supportedRefreshRatesArrayValues[i] = static_cast<jfloat>(info.supportedRefreshRates[i]);
+ }
+ env->ReleaseFloatArrayElements(supportedRefreshRatesArray, supportedRefreshRatesArrayValues, 0);
+ env->SetObjectField(object, gDynamicDisplayInfoClassInfo.supportedRefreshRates,
+ supportedRefreshRatesArray);
+
jintArray colorModesArray = env->NewIntArray(info.supportedColorModes.size());
if (colorModesArray == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
@@ -2766,6 +2782,8 @@ int register_android_view_SurfaceControl(JNIEnv* env)
gFrameRateCategoryRateClassInfo.ctor =
GetMethodIDOrDie(env, frameRateCategoryRateClazz, "<init>", "(FF)V");
+ gDynamicDisplayInfoClassInfo.supportedRefreshRates =
+ GetFieldIDOrDie(env, dynamicInfoClazz, "supportedRefreshRates", "[F");
gDynamicDisplayInfoClassInfo.supportedColorModes =
GetFieldIDOrDie(env, dynamicInfoClazz, "supportedColorModes", "[I");
gDynamicDisplayInfoClassInfo.activeColorMode =
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 6af742fb23f4..2e0fe9eb13d9 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -256,6 +256,12 @@ message SecureSettingsProto {
}
optional Display display = 100;
+ message DoubleTapPowerButton {
+ optional SettingProto gesture_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto gesture = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional DoubleTapPowerButton double_tap_power_button = 103;
+
message Doze {
option (android.msg_privacy).dest = DEST_EXPLICIT;
@@ -737,5 +743,5 @@ message SecureSettingsProto {
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 103;
+ // Next tag = 104;
}
diff --git a/core/res/Android.bp b/core/res/Android.bp
index 8042b30df4dc..aacd8699c202 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -160,6 +160,7 @@ android_app {
"android.app.contextualsearch.flags-aconfig",
"android.app.flags-aconfig",
"android.appwidget.flags-aconfig",
+ "android.companion.virtualdevice.flags-aconfig",
"android.content.pm.flags-aconfig",
"android.media.audio-aconfig",
"android.provider.flags-aconfig",
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cedcd2feafc3..7c2a30da4923 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -848,10 +848,10 @@
<protected-broadcast android:name="android.app.action.CONSOLIDATED_NOTIFICATION_POLICY_CHANGED" />
<protected-broadcast android:name="android.intent.action.MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED" />
<protected-broadcast android:name="com.android.uwb.uwbcountrycode.GEOCODE_RETRY" />
- <protected-broadcast android:name="android.telephony.action.ACTION_SATELLITE_SUBSCRIBER_ID_LIST_CHANGED" />
+ <protected-broadcast android:name="android.telephony.satellite.action.SATELLITE_SUBSCRIBER_ID_LIST_CHANGED" />
<protected-broadcast android:name="android.service.ondeviceintelligence.MODEL_LOADED" />
<protected-broadcast android:name="android.service.ondeviceintelligence.MODEL_UNLOADED" />
- <protected-broadcast android:name="android.telephony.action.ACTION_SATELLITE_START_NON_EMERGENCY_SESSION" />
+ <protected-broadcast android:name="android.telephony.satellite.action.SATELLITE_START_NON_EMERGENCY_SESSION" />
<!-- ====================================================================== -->
@@ -8060,6 +8060,13 @@
<permission android:name="android.permission.ADD_ALWAYS_UNLOCKED_DISPLAY"
android:protectionLevel="signature|role"/>
+ <!-- Allows an application to create displays that mirror other displays' content.
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ENABLE_LIMITED_VDM_ROLE)
+ @hide @SystemApi -->
+ <permission android:name="android.permission.ADD_MIRROR_DISPLAY"
+ android:protectionLevel="internal|role"
+ android:featureFlag="android.companion.virtualdevice.flags.enable_limited_vdm_role" />
+
<!-- @hide @SystemApi Allows an application to access locusId events in the usage stats. -->
<permission android:name="android.permission.ACCESS_LOCUS_ID_USAGE_STATS"
android:protectionLevel="signature|role" />
@@ -9344,6 +9351,17 @@
</intent-filter>
</service>
+ <service android:name="com.android.ecm.EnhancedConfirmationCallTrackerService"
+ android:permission="android.permission.BIND_INCALL_SERVICE"
+ android:featureFlag="android.permission.flags.enhanced_confirmation_in_call_apis_enabled"
+ android:exported="true">
+ <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
+ android:value="true" />
+ <intent-filter>
+ <action android:name="android.telecom.InCallService"/>
+ </intent-filter>
+ </service>
+
<service android:name="com.android.server.companion.datatransfer.contextsync.CallMetadataSyncConnectionService"
android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
android:exported="true">
diff --git a/core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml b/core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml
index b6b8eac3a547..0314bbec2b55 100644
--- a/core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml
+++ b/core/res/res/drawable-watch-v36/dialog_alert_button_background_negative.xml
@@ -18,7 +18,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/btn_material_filled_tonal_background_color"/>
- <corners android:radius="@dimen/config_bottomDialogCornerRadius" />
+ <corners android:radius="@dimen/config_wearMaterial3_bottomDialogCornerRadius" />
<size
android:width="@dimen/dialog_btn_negative_width"
android:height="@dimen/dialog_btn_negative_height" />
diff --git a/core/res/res/layout-sw600dp/preference_list_content_single.xml b/core/res/res/layout-sw600dp/preference_list_content_single.xml
index 88b1aa8d4d00..ebe4eca1b156 100644
--- a/core/res/res/layout-sw600dp/preference_list_content_single.xml
+++ b/core/res/res/layout-sw600dp/preference_list_content_single.xml
@@ -19,6 +19,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
+ android:fitsSystemWindows="true"
android:layout_height="match_parent"
android:layout_width="match_parent">
diff --git a/core/res/res/layout-watch-v36/alert_dialog_icon_button_wear_material3.xml b/core/res/res/layout-watch-v36/alert_dialog_icon_button_wear_material3.xml
new file mode 100644
index 000000000000..407ec7a42740
--- /dev/null
+++ b/core/res/res/layout-watch-v36/alert_dialog_icon_button_wear_material3.xml
@@ -0,0 +1,123 @@
+<!--
+ ~ 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.
+ -->
+
+<!-- This layout is the AlertDialog template. It overrides the system layout with the same name.
+ Make sure to include all the existing id of the overridden alert_dialog_material.-->
+<com.android.internal.widget.WatchListDecorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/parentPanel"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ScrollView
+ android:id="@+id/scrollView"
+ android:fillViewport="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <!-- Top Panel -->
+ <FrameLayout
+ android:paddingLeft="?dialogPreferredPadding"
+ android:paddingRight="?dialogPreferredPadding"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/topPanel"
+ android:minHeight="@dimen/dialog_list_padding_top_no_title">
+ <include android:id="@+id/title_template"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ layout="@layout/alert_dialog_title_material"/>
+ </FrameLayout>
+
+ <!-- Content Panel -->
+ <FrameLayout android:id="@+id/contentPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false">
+ <TextView android:id="@+id/message"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal|top"
+ android:textAppearance="@style/TextAppearance.DeviceDefault.Body1"
+ android:paddingStart="?dialogPreferredPadding"
+ android:paddingEnd="?dialogPreferredPadding"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"/>
+ </FrameLayout>
+
+ <!-- Custom Panel, to replace content panel if needed -->
+ <FrameLayout android:id="@+id/customPanel"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:minHeight="64dp">
+ <FrameLayout android:id="@+android:id/custom"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </FrameLayout>
+
+ <!-- Button Panel -->
+ <FrameLayout
+ android:id="@+id/buttonPanel"
+ android:minHeight="@dimen/dialog_list_padding_bottom_no_buttons"
+ android:layout_weight="1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center">
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:orientation="horizontal"
+ android:paddingBottom="?dialogPreferredPadding"
+ style="?android:attr/buttonBarStyle"
+ android:measureWithLargestChild="true">
+ <Button android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:layout_weight="1"
+ style="@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Negative" />
+ <Button android:id="@+id/button3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:layout_weight="1"
+ style="?android:attr/buttonBarButtonStyle"/>
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ <Button android:id="@+id/button1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:layout_weight="1"
+ style="@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Confirm" />
+ <!-- This works as background. -->
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@drawable/dialog_alert_button_positive"/>
+ </FrameLayout>
+ </LinearLayout>
+ </FrameLayout>
+ </LinearLayout>
+ </ScrollView>
+</com.android.internal.widget.WatchListDecorLayout>
diff --git a/core/res/res/layout-watch-v36/alert_dialog_material.xml b/core/res/res/layout-watch-v36/alert_dialog_material.xml
index 900102f379d9..8f7545690142 100644
--- a/core/res/res/layout-watch-v36/alert_dialog_material.xml
+++ b/core/res/res/layout-watch-v36/alert_dialog_material.xml
@@ -82,9 +82,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
- android:orientation="horizontal"
+ android:orientation="vertical"
android:paddingBottom="?dialogPreferredPadding"
- style="?android:attr/buttonBarStyle"
android:measureWithLargestChild="true">
<Button android:id="@+id/button2"
android:layout_width="wrap_content"
@@ -92,7 +91,7 @@
android:layout_gravity="center"
android:gravity="center"
android:layout_weight="1"
- style="@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog.Negative" />
+ style="@*android:style/Widget.DeviceDefault.Button.WearMaterial3"/>
<Button android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -100,22 +99,13 @@
android:gravity="center"
android:layout_weight="1"
style="?android:attr/buttonBarButtonStyle"/>
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <Button android:id="@+id/button1"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:gravity="center"
- android:layout_weight="1"
- style="@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog.Confirm"/>
- <!-- This works as background. -->
- <ImageView
+ <Button android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:src="@drawable/dialog_alert_button_positive"/>
- </FrameLayout>
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:layout_weight="1"
+ style="@*android:style/Widget.DeviceDefault.Button.Filled"/>
</LinearLayout>
</FrameLayout>
</LinearLayout>
diff --git a/core/res/res/layout/notification_2025_reply_container.xml b/core/res/res/layout/notification_2025_reply_container.xml
new file mode 100644
index 000000000000..6923b59f34dc
--- /dev/null
+++ b/core/res/res/layout/notification_2025_reply_container.xml
@@ -0,0 +1,79 @@
+<?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
+ -->
+
+<!-- Note: this layout is included from a view stub; layout attributes will be overridden. -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/notification_material_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingStart="@dimen/notification_2025_content_margin_start">
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:id="@+id/action_divider"
+ android:layout_marginTop="@dimen/notification_content_margin"
+ android:layout_marginBottom="@dimen/notification_content_margin"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:background="@drawable/notification_template_divider" />
+
+ <TextView
+ android:id="@+id/notification_material_reply_text_3"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:visibility="gone"
+ android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
+ android:singleLine="true" />
+
+ <TextView
+ android:id="@+id/notification_material_reply_text_2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:visibility="gone"
+ android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
+ android:singleLine="true" />
+
+ <LinearLayout
+ android:id="@+id/notification_material_reply_text_1_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginEnd="@dimen/notification_content_margin_end">
+ <TextView
+ android:id="@+id/notification_material_reply_text_1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:layout_gravity="center"
+ android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
+ android:singleLine="true" />
+ <ProgressBar
+ android:id="@+id/notification_material_reply_progress"
+ android:layout_height="@dimen/messaging_group_sending_progress_size"
+ android:layout_width="@dimen/messaging_group_sending_progress_size"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_gravity="center"
+ android:indeterminate="true"
+ style="?android:attr/progressBarStyleSmall" />
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_base.xml b/core/res/res/layout/notification_2025_template_expanded_base.xml
new file mode 100644
index 000000000000..e480fe5eef1e
--- /dev/null
+++ b/core/res/res/layout/notification_2025_template_expanded_base.xml
@@ -0,0 +1,86 @@
+<?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
+ -->
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:clipChildren="false"
+ android:tag="big"
+ >
+
+ <LinearLayout
+ android:id="@+id/notification_action_list_margin_target"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/notification_content_margin"
+ android:orientation="vertical"
+ >
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="top"
+ >
+
+ <include layout="@layout/notification_2025_template_header" />
+
+ <LinearLayout
+ android:id="@+id/notification_main_column"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:layout_marginTop="@dimen/notification_content_margin_top"
+ android:orientation="vertical"
+ >
+
+ <include layout="@layout/notification_template_part_line1" />
+
+ <include layout="@layout/notification_template_text_multiline" />
+
+ <include
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_progress_bar_height"
+ android:layout_marginTop="@dimen/notification_progress_margin_top"
+ layout="@layout/notification_template_progress"
+ />
+ </LinearLayout>
+
+ <include layout="@layout/notification_template_right_icon" />
+ </FrameLayout>
+
+ <ViewStub
+ android:layout="@layout/notification_2025_reply_container"
+ android:id="@+id/notification_material_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+ <include
+ layout="@layout/notification_template_smart_reply_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+ android:layout_marginEnd="@dimen/notification_content_margin_end"
+ android:layout_marginTop="@dimen/notification_content_margin"
+ />
+
+ <include layout="@layout/notification_material_action_list" />
+ </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 565d584875ac..57959361bd48 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -13,7 +13,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<!-- extends FrameLayout -->
+<!-- extends RelativeLayout -->
<NotificationHeaderView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/notification_header"
@@ -62,7 +62,7 @@
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
- android:layout_toStartOf="@id/notification_buttons_column"
+ android:layout_toStartOf="@id/expand_button"
android:layout_alignWithParentIfMissing="true"
android:clipChildren="false"
android:gravity="center_vertical"
@@ -83,28 +83,17 @@
android:focusable="false"
/>
- <LinearLayout
- android:id="@+id/notification_buttons_column"
+ <include layout="@layout/notification_expand_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:orientation="vertical"
- >
-
- <include layout="@layout/notification_close_button"
- android:layout_width="@dimen/notification_close_button_size"
- android:layout_height="@dimen/notification_close_button_size"
- android:layout_gravity="end"
- android:layout_marginEnd="20dp"
- />
-
- <include layout="@layout/notification_expand_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_centerVertical="true"
- />
+ android:layout_centerVertical="true"
+ android:layout_alignParentEnd="true" />
- </LinearLayout>
+ <include layout="@layout/notification_close_button"
+ android:id="@+id/close_button"
+ android:layout_width="@dimen/notification_close_button_size"
+ android:layout_height="@dimen/notification_close_button_size"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentEnd="true" />
</NotificationHeaderView>
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index 29f14a4a93fc..227f84bb2eed 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -157,39 +157,27 @@
android:maxDrawableHeight="@dimen/notification_right_icon_size"
/>
- <LinearLayout
- android:id="@+id/notification_buttons_column"
+ <FrameLayout
+ android:id="@+id/expand_button_touch_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_alignParentEnd="true"
- android:orientation="vertical"
+ android:minWidth="@dimen/notification_content_margin_end"
>
- <include layout="@layout/notification_close_button"
- android:layout_width="@dimen/notification_close_button_size"
- android:layout_height="@dimen/notification_close_button_size"
- android:layout_gravity="end"
- android:layout_marginEnd="20dp"
- />
-
- <FrameLayout
- android:id="@+id/expand_button_touch_container"
+ <include layout="@layout/notification_expand_button"
android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:minWidth="@dimen/notification_content_margin_end"
- >
-
- <include layout="@layout/notification_expand_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical|end"
- />
-
- </FrameLayout>
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical|end"
+ />
- </LinearLayout>
+ </FrameLayout>
</LinearLayout>
+ <include layout="@layout/notification_close_button"
+ android:id="@+id/close_button"
+ android:layout_width="@dimen/notification_close_button_size"
+ android:layout_height="@dimen/notification_close_button_size"
+ android:layout_gravity="top|end" />
+
</FrameLayout>
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 6e9d17fc31d4..5459fa895f82 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -15,6 +15,7 @@
~ limitations under the License
-->
+<!-- extends FrameLayout -->
<com.android.internal.widget.MediaNotificationView
android:id="@+id/status_bar_latest_event_content"
xmlns:android="http://schemas.android.com/apk/res/android"
@@ -191,4 +192,11 @@
</FrameLayout>
</LinearLayout>
+
+ <include layout="@layout/notification_close_button"
+ android:id="@+id/close_button"
+ android:layout_width="@dimen/notification_close_button_size"
+ android:layout_height="@dimen/notification_close_button_size"
+ android:layout_gravity="top|end" />
+
</com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/layout/notification_template_material_messaging.xml b/core/res/res/layout/notification_template_material_messaging.xml
index 1eae41da1e81..2b3b7d873f4f 100644
--- a/core/res/res/layout/notification_template_material_messaging.xml
+++ b/core/res/res/layout/notification_template_material_messaging.xml
@@ -195,6 +195,12 @@
</LinearLayout>
+ <include layout="@layout/notification_close_button"
+ android:id="@+id/close_button"
+ android:layout_width="@dimen/notification_close_button_size"
+ android:layout_height="@dimen/notification_close_button_size"
+ android:layout_gravity="top|end" />
+
</com.android.internal.widget.NotificationMaxHeightFrameLayout>
<LinearLayout
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index bed80edf0ee7..7a2fb0b3b822 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -20,6 +20,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
+ android:fitsSystemWindows="true"
android:layout_height="match_parent"
android:layout_width="match_parent">
diff --git a/core/res/res/layout/preference_list_content_material.xml b/core/res/res/layout/preference_list_content_material.xml
index 37b411918ef6..23c82509b6b0 100644
--- a/core/res/res/layout/preference_list_content_material.xml
+++ b/core/res/res/layout/preference_list_content_material.xml
@@ -20,6 +20,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
+ android:fitsSystemWindows="true"
android:layout_height="match_parent"
android:layout_width="match_parent">
diff --git a/core/res/res/layout/preference_list_content_single.xml b/core/res/res/layout/preference_list_content_single.xml
index 726ce78b281f..4f072da99546 100644
--- a/core/res/res/layout/preference_list_content_single.xml
+++ b/core/res/res/layout/preference_list_content_single.xml
@@ -19,6 +19,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
+ android:fitsSystemWindows="true"
android:layout_height="match_parent"
android:layout_width="match_parent">
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index c43975e4ad3c..44a5df9b60be 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -19,6 +19,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
+ android:fitsSystemWindows="true"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@android:color/transparent"
diff --git a/core/res/res/layout/preference_list_fragment_material.xml b/core/res/res/layout/preference_list_fragment_material.xml
index db2fe7d038e0..4df76029e606 100644
--- a/core/res/res/layout/preference_list_fragment_material.xml
+++ b/core/res/res/layout/preference_list_fragment_material.xml
@@ -19,6 +19,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
+ android:fitsSystemWindows="true"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@android:color/transparent"
diff --git a/core/res/res/values-watch-v36/config.xml b/core/res/res/values-watch-v36/config.xml
index 1143ae30fe9d..679dc709ec35 100644
--- a/core/res/res/values-watch-v36/config.xml
+++ b/core/res/res/values-watch-v36/config.xml
@@ -16,5 +16,5 @@
<resources>
<dimen name="config_wearMaterial3_buttonCornerRadius">26dp</dimen>
- <dimen name="config_bottomDialogCornerRadius">18dp</dimen>
+ <dimen name="config_wearMaterial3_bottomDialogCornerRadius">18dp</dimen>
</resources>
diff --git a/core/res/res/values-watch-v36/styles_material.xml b/core/res/res/values-watch-v36/styles_material.xml
index 00f3f092b768..7da7435930b1 100644
--- a/core/res/res/values-watch-v36/styles_material.xml
+++ b/core/res/res/values-watch-v36/styles_material.xml
@@ -57,7 +57,7 @@
</style>
<!-- AlertDialog Styles -->
- <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog" parent="Widget.DeviceDefault.Button">
+ <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3" parent="Widget.DeviceDefault.Button">
<item name="android:textSize">0sp</item>
<item name="android:gravity">center</item>
<item name="android:paddingStart">0dp</item>
@@ -65,14 +65,14 @@
<item name="android:drawablePadding">0dp</item>
</style>
- <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.Confirm" parent="Widget.DeviceDefault.Button.ButtonBar.AlertDialog">
+ <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Confirm">
<!-- Use a ImageView as background -->
<item name="background">@android:color/transparent</item>
<item name="minWidth">@dimen/dialog_btn_confirm_width</item>
<item name="minHeight">@dimen/dialog_btn_confirm_height</item>
</style>
- <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.Negative" parent="Widget.DeviceDefault.Button.ButtonBar.AlertDialog">
+ <style name="Widget.DeviceDefault.Button.ButtonBar.AlertDialog.WearMaterial3.Negative">
<item name="background">@drawable/dialog_alert_button_negative</item>
<item name="minWidth">@dimen/dialog_btn_negative_width</item>
<item name="minHeight">@dimen/dialog_btn_negative_height</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index f6590b1360f8..8c46ccc84f39 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4808,6 +4808,12 @@
<!-- Whether the device should default to observe mode when this service is
default or in the foreground. -->
<attr name="shouldDefaultToObserveMode" format="boolean"/>
+ <!-- Whether this service should share the same AID routing priority as the role
+ owner. This package and the role owner must have the same signature, and the
+ role owner must opt into this behavior by using the property named by
+ {@link android.nfc.cardemulation.CardEmulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY }
+ in the <code>&lt;application&rt;</code> tag. -->
+ <attr name="shareRolePriority" format="boolean"/>
</declare-styleable>
<!-- Use <code>offhost-apdu-service</code> as the root tag of the XML resource that
@@ -4835,6 +4841,7 @@
<!-- Whether the device should default to observe mode when this service is
default or in the foreground. -->
<attr name="shouldDefaultToObserveMode"/>
+ <attr name="shareRolePriority"/>
</declare-styleable>
<!-- Specify one or more <code>aid-group</code> elements inside a
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7f2c816e5654..38ebda733270 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2731,6 +2731,8 @@
</string-array>
<!-- The list of supported dream complications -->
<integer-array name="config_supportedDreamComplications">
+ <!-- COMPLICATION_TYPE_TIME -->
+ <item>1</item>
</integer-array>
<!-- Are we allowed to dream while not plugged in? -->
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index e71277dc0414..3b39a65b6795 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -290,4 +290,7 @@
<!-- View tag associating a view with its overridden id, to ensure valid recycling only. -->
<item type="id" name="remote_views_override_id" />
+
+ <!-- View tag associating a view with its id for widget metrics. -->
+ <item type="id" name="remoteViewsMetricsId" />
</resources>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index b0b87d1dead6..e75371d6bf46 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -133,9 +133,13 @@
<public name="alternateLauncherLabels"/>
<!-- @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB) -->
<public name="pageSizeCompat" />
+ <!-- @FlaggedApi(android.nfc.Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES) -->
+ <public name="shareRolePriority"/>
</staging-public-group>
<staging-public-group type="id" first-id="0x01b60000">
+ <!-- @FlaggedApi(android.appwidget.flags.Flags.FLAG_ENGAGEMENT_METRICS) -->
+ <public name="remoteViewsMetricsId"/>
</staging-public-group>
<staging-public-group type="style" first-id="0x01b50000">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c13fdb17dfe3..413f0c3e0c58 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5357,6 +5357,8 @@
<string name="zen_mode_trigger_summary_range_symbol_combination"><xliff:g id="start" example="Sun">%1$s</xliff:g> - <xliff:g id="end" example="Thu">%2$s</xliff:g></string>
<!-- [CHAR LIMIT=40] General template for a start - end range in a text summary, used for the trigger description of a Zen mode -->
<string name="zen_mode_trigger_summary_range_words"><xliff:g id="start" example="Sunday">%1$s</xliff:g> to <xliff:g id="end" example="Thursday">%2$s</xliff:g></string>
+ <!-- [CHAR LIMIT=NONE] General template for combining a days of week start-end range with a time-based start-end range, for example: "Sun-Thurs, 10:00 PM - 7:00 AM" -->
+ <string name="zen_mode_trigger_summary_combined"><xliff:g id="days" example="Sat-Thurs">%1$s</xliff:g>,\u0020<xliff:g id="times" example="10:00 PM - 7:00 AM">%2$s</xliff:g></string>
<!-- [CHAR LIMIT=40] Event-based rule calendar option value for any calendar, used for the trigger description of a Zen mode -->
<string name="zen_mode_trigger_event_calendar_any">Any calendar</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b49e142e4cee..fc24f4599b25 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2390,6 +2390,7 @@
<java-symbol type="layout" name="notification_material_action_list" />
<java-symbol type="layout" name="notification_material_action_tombstone" />
<java-symbol type="layout" name="notification_2025_template_collapsed_base" />
+ <java-symbol type="layout" name="notification_2025_template_expanded_base" />
<java-symbol type="layout" name="notification_2025_template_heads_up_base" />
<java-symbol type="layout" name="notification_2025_template_header" />
<java-symbol type="layout" name="notification_template_material_base" />
@@ -2666,6 +2667,7 @@
<java-symbol type="string" name="zen_mode_trigger_summary_divider_text" />
<java-symbol type="string" name="zen_mode_trigger_summary_range_symbol_combination" />
<java-symbol type="string" name="zen_mode_trigger_summary_range_words" />
+ <java-symbol type="string" name="zen_mode_trigger_summary_combined" />
<java-symbol type="string" name="zen_mode_trigger_event_calendar_any" />
<java-symbol type="string" name="display_rotation_camera_compat_toast_after_rotation" />
@@ -5109,7 +5111,6 @@
<java-symbol type="layout" name="notification_expand_button"/>
<java-symbol type="id" name="close_button" />
<java-symbol type="layout" name="notification_close_button"/>
- <java-symbol type="id" name="notification_buttons_column" />
<java-symbol type="bool" name="config_supportsMicToggle" />
<java-symbol type="bool" name="config_supportsCamToggle" />
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index f39508d6de15..49425572b256 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -152,6 +152,7 @@ android_test {
":HelloWorldUsingSdkMalformedNegativeVersion",
":CtsStaticSharedLibConsumerApp1",
":CtsStaticSharedLibConsumerApp3",
+ ":CtsStaticSharedLibProviderApp1",
],
}
diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml
index 5d8ff87eca24..bada7512a8e9 100644
--- a/core/tests/coretests/AndroidTest.xml
+++ b/core/tests/coretests/AndroidTest.xml
@@ -43,6 +43,8 @@
value="/data/local/tmp/tests/coretests/pm/CtsStaticSharedLibConsumerApp1.apk"/>
<option name="push-file" key="CtsStaticSharedLibConsumerApp3.apk"
value="/data/local/tmp/tests/coretests/pm/CtsStaticSharedLibConsumerApp3.apk"/>
+ <option name="push-file" key="CtsStaticSharedLibProviderApp1.apk"
+ value="/data/local/tmp/tests/coretests/pm/CtsStaticSharedLibProviderApp1.apk"/>
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index 23a09857032c..63e678d9ee53 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -467,7 +467,6 @@ public class NotificationTest {
.setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG"))
.setColor(Color.WHITE)
.setColorized(true)
- .setFlag(FLAG_CAN_COLORIZE, true)
.build();
assertThat(n.hasPromotableCharacteristics()).isTrue();
}
@@ -481,7 +480,6 @@ public class NotificationTest {
.setContentTitle("TITLE")
.setColor(Color.WHITE)
.setColorized(true)
- .setFlag(FLAG_CAN_COLORIZE, true)
.build();
assertThat(n.hasPromotableCharacteristics()).isFalse();
}
@@ -505,7 +503,20 @@ public class NotificationTest {
.setStyle(new Notification.BigTextStyle())
.setColor(Color.WHITE)
.setColorized(true)
- .setFlag(FLAG_CAN_COLORIZE, true)
+ .build();
+ assertThat(n.hasPromotableCharacteristics()).isFalse();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_UI_RICH_ONGOING)
+ public void testHasPromotableCharacteristics_groupSummary() {
+ Notification n = new Notification.Builder(mContext, "test")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .setStyle(new Notification.BigTextStyle().setBigContentTitle("BIG"))
+ .setColor(Color.WHITE)
+ .setColorized(true)
+ .setGroup("someGroup")
+ .setGroupSummary(true)
.build();
assertThat(n.hasPromotableCharacteristics()).isFalse();
}
diff --git a/core/tests/coretests/src/android/appwidget/AppWidgetEventsTest.kt b/core/tests/coretests/src/android/appwidget/AppWidgetEventsTest.kt
new file mode 100644
index 000000000000..ea1158c88055
--- /dev/null
+++ b/core/tests/coretests/src/android/appwidget/AppWidgetEventsTest.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 android.appwidget
+
+import android.graphics.Rect
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class AppWidgetEventsTest {
+ @Test
+ fun createWidgetInteractionEvent() {
+ val appWidgetId = 1
+ val durationMs = 1000L
+ val position = Rect(1, 2, 3, 4)
+ val clicked = intArrayOf(1, 2, 3)
+ val scrolled = intArrayOf(4, 5, 6)
+ val bundle = AppWidgetManager.createWidgetInteractionEvent(
+ appWidgetId,
+ durationMs,
+ position,
+ clicked,
+ scrolled
+ )
+
+ assertThat(bundle.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID)).isEqualTo(appWidgetId)
+ assertThat(bundle.getLong(AppWidgetManager.EXTRA_EVENT_DURATION_MS)).isEqualTo(durationMs)
+ assertThat(bundle.getIntArray(AppWidgetManager.EXTRA_EVENT_POSITION_RECT))
+ .asList().containsExactly(position.left, position.top, position.right, position.bottom)
+ assertThat(bundle.getIntArray(AppWidgetManager.EXTRA_EVENT_CLICKED_VIEWS))
+ .asList().containsExactly(clicked[0], clicked[1], clicked[2])
+ assertThat(bundle.getIntArray(AppWidgetManager.EXTRA_EVENT_SCROLLED_VIEWS))
+ .asList().containsExactly(scrolled[0], scrolled[1], scrolled[2])
+ }
+}
diff --git a/core/tests/coretests/src/android/appwidget/OWNERS b/core/tests/coretests/src/android/appwidget/OWNERS
new file mode 100644
index 000000000000..d724cac4aa3e
--- /dev/null
+++ b/core/tests/coretests/src/android/appwidget/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/appwidget/OWNERS
diff --git a/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java b/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
index ecacdb2bde0b..6d2dd5355ff0 100644
--- a/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
+++ b/core/tests/coretests/src/android/content/pm/parsing/ApkLiteParseUtilsTest.java
@@ -73,6 +73,7 @@ public class ApkLiteParseUtilsTest {
private static final String TEST_APP_USING_SDK1_AND_SDK1 = "HelloWorldUsingSdk1AndSdk1.apk";
private static final String TEST_APP_USING_SDK_MALFORMED_VERSION =
"HelloWorldUsingSdkMalformedNegativeVersion.apk";
+ private static final String TEST_STATIC_LIB_APP = "CtsStaticSharedLibProviderApp1.apk";
private static final String TEST_APP_USING_STATIC_LIB = "CtsStaticSharedLibConsumerApp1.apk";
private static final String TEST_APP_USING_STATIC_LIB_TWO_CERTS =
"CtsStaticSharedLibConsumerApp3.apk";
@@ -207,6 +208,17 @@ public class ApkLiteParseUtilsTest {
assertThat(liteCerts).isEqualTo(pkgCerts);
}
+ @Test
+ public void testParseApkLite_isIsStaticLibrary() throws Exception {
+ File apkFile = copyApkToTmpDir(TEST_STATIC_LIB_APP);
+ ParseResult<ApkLite> result = ApkLiteParseUtils
+ .parseApkLite(ParseTypeImpl.forDefaultParsing().reset(), apkFile, 0);
+ assertThat(result.isError()).isFalse();
+ ApkLite baseApk = result.getResult();
+
+ assertThat(baseApk.isIsStaticLibrary()).isTrue();
+ }
+
@SuppressLint("CheckResult")
@Test
public void testParseApkLite_malformedUsesSdkLibrary_duplicate() throws Exception {
diff --git a/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java b/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java
index a3725af04ba6..bb2fe1bcfc64 100644
--- a/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java
+++ b/core/tests/coretests/src/android/window/WindowTokenClientControllerTest.java
@@ -162,6 +162,22 @@ public class WindowTokenClientControllerTest {
}
@Test
+ public void testAttachToDisplayContent_keepTrackWithoutWMS() {
+ // WMS is not initialized
+ doReturn(null).when(mController).getWindowManagerService();
+
+ assertFalse(mController.attachToDisplayContent(mWindowTokenClient, DEFAULT_DISPLAY));
+
+ // Can report config change
+ mController.onWindowContextInfoChanged(mWindowTokenClient, mWindowContextInfo);
+
+ verify(mWindowTokenClient).onConfigurationChanged(mConfiguration, DEFAULT_DISPLAY);
+
+ // No crash to detach even if WMS is not initialized.
+ mController.detachIfNeeded(mWindowTokenClient);
+ }
+
+ @Test
public void testAttachToWindowToken() throws RemoteException {
doReturn(null).when(mWindowManagerService).attachWindowContextToWindowToken(
any(), any(), any());
diff --git a/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java b/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java
index 1cc38ded1c2c..40710577b154 100644
--- a/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java
+++ b/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java
@@ -16,6 +16,8 @@
package android.os.vibrator.persistence;
+import static android.os.VibrationEffect.Composition.DELAY_TYPE_PAUSE;
+import static android.os.VibrationEffect.Composition.DELAY_TYPE_RELATIVE_START_OFFSET;
import static android.os.VibrationEffect.Composition.PRIMITIVE_CLICK;
import static android.os.VibrationEffect.Composition.PRIMITIVE_LOW_TICK;
import static android.os.VibrationEffect.Composition.PRIMITIVE_SPIN;
@@ -31,6 +33,7 @@ import android.os.PersistableBundle;
import android.os.VibrationEffect;
import android.os.vibrator.Flags;
import android.os.vibrator.PrebakedSegment;
+import android.os.vibrator.PrimitiveSegment;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
@@ -437,7 +440,7 @@ public class VibrationEffectXmlSerializationTest {
@Test
@EnableFlags(Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
- public void testVendorEffect_featureFlagEnabled_allSucceed() throws Exception {
+ public void testVendorEffect_allSucceed() throws Exception {
PersistableBundle vendorData = new PersistableBundle();
vendorData.putInt("id", 1);
vendorData.putDouble("scale", 0.5);
@@ -476,7 +479,7 @@ public class VibrationEffectXmlSerializationTest {
@Test
@EnableFlags(Flags.FLAG_VENDOR_VIBRATION_EFFECTS)
- public void testInvalidVendorEffect_featureFlagEnabled_allFail() throws IOException {
+ public void testInvalidVendorEffect_allFail() throws IOException {
String emptyTag = "<vibration-effect><vendor-effect/></vibration-effect>";
assertPublicApisParserFails(emptyTag);
assertHiddenApisParserFails(emptyTag);
@@ -526,6 +529,81 @@ public class VibrationEffectXmlSerializationTest {
assertHiddenApisSerializerFails(vendorEffect);
}
+ @Test
+ @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY)
+ public void testPrimitiveDelayType_allSucceed() throws Exception {
+ VibrationEffect effect = VibrationEffect.startComposition()
+ .addPrimitive(PRIMITIVE_TICK, 1.0f, 0, DELAY_TYPE_RELATIVE_START_OFFSET)
+ .addPrimitive(PRIMITIVE_CLICK, 0.123f, 10, DELAY_TYPE_PAUSE)
+ .compose();
+ String xml = """
+ <vibration-effect>
+ <primitive-effect name="tick" delayType="relative_start_offset"/>
+ <primitive-effect name="click" scale="0.123" delayMs="10"/>
+ </vibration-effect>
+ """;
+
+ assertPublicApisParserSucceeds(xml, effect);
+ assertPublicApisSerializerSucceeds(effect, "tick", "click");
+ // Delay type pause is not serialized, as it's the default one
+ assertPublicApisSerializerSucceeds(effect, "relative_start_offset", "click");
+ assertPublicApisRoundTrip(effect);
+
+ assertHiddenApisParserSucceeds(xml, effect);
+ assertHiddenApisSerializerSucceeds(effect, "tick", "click");
+ assertHiddenApisRoundTrip(effect);
+
+ // Check PersistableBundle from round-trip
+ VibrationEffect.Composed parsedEffect = ((VibrationEffect.Composed) parseVibrationEffect(
+ serialize(effect), /* flags= */ 0));
+ assertThat(parsedEffect.getRepeatIndex()).isEqualTo(-1);
+ assertThat(parsedEffect.getSegments()).containsExactly(
+ new PrimitiveSegment(PRIMITIVE_TICK, 1.0f, 0, DELAY_TYPE_RELATIVE_START_OFFSET),
+ new PrimitiveSegment(PRIMITIVE_CLICK, 0.123f, 10, DELAY_TYPE_PAUSE))
+ .inOrder();
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY)
+ public void testPrimitiveInvalidDelayType_allFail() {
+ String emptyAttribute = """
+ <vibration-effect>
+ <primitive-effect name="tick" delayType=""/>
+ </vibration-effect>
+ """;
+ assertPublicApisParserFails(emptyAttribute);
+ assertHiddenApisParserFails(emptyAttribute);
+
+ String invalidString = """
+ <vibration-effect>
+ <primitive-effect name="tick" delayType="invalid"/>
+ </vibration-effect>
+ """;
+ assertPublicApisParserFails(invalidString);
+ assertHiddenApisParserFails(invalidString);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_PRIMITIVE_COMPOSITION_ABSOLUTE_DELAY)
+ public void testPrimitiveDelayType_featureFlagDisabled_allFail() {
+ VibrationEffect effect = VibrationEffect.startComposition()
+ .addPrimitive(PRIMITIVE_TICK, 1.0f, 0, DELAY_TYPE_RELATIVE_START_OFFSET)
+ .addPrimitive(PRIMITIVE_CLICK, 0.123f, 10, DELAY_TYPE_PAUSE)
+ .compose();
+ String xml = """
+ <vibration-effect>
+ <primitive-effect name="tick" delayType="relative_start_offset"/>
+ <primitive-effect name="click" scale="0.123" delayMs="10" delayType="pause"/>
+ </vibration-effect>
+ """;
+
+ assertPublicApisParserFails(xml);
+ assertPublicApisSerializerFails(effect);
+
+ assertHiddenApisParserFails(xml);
+ assertHiddenApisSerializerFails(effect);
+ }
+
private void assertPublicApisParserFails(String xml) {
assertThrows("Expected parseVibrationEffect to fail for " + xml,
VibrationXmlParser.ParseFailedException.class,
diff --git a/core/xsd/permission.xsd b/core/xsd/permission.xsd
index 0ec8f7d4f2ae..0a0ca7c2248b 100644
--- a/core/xsd/permission.xsd
+++ b/core/xsd/permission.xsd
@@ -43,6 +43,7 @@
<xs:element name="disabled-until-used-preinstalled-carrier-app" type="disabled-until-used-preinstalled-carrier-app"/>
<xs:element name="privapp-permissions" type="privapp-permissions"/>
<xs:element name="oem-permissions" type="oem-permissions"/>
+ <xs:element name="signature-permissions" type="signature-permissions"/>
<xs:element name="hidden-api-whitelisted-app" type="hidden-api-whitelisted-app"/>
<xs:element name="allow-association" type="allow-association"/>
<xs:element name="bugreport-whitelisted" type="bugreport-whitelisted"/>
@@ -156,6 +157,21 @@
</xs:sequence>
<xs:attribute name="package" type="xs:string"/>
</xs:complexType>
+ <xs:complexType name="signature-permissions">
+ <xs:sequence>
+ <xs:element name="permission" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="deny-permission" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
<xs:complexType name="hidden-api-whitelisted-app">
<xs:attribute name="package" type="xs:string"/>
</xs:complexType>
diff --git a/core/xsd/schema/current.txt b/core/xsd/schema/current.txt
index f3beea1b96a9..cdec6ab6e014 100644
--- a/core/xsd/schema/current.txt
+++ b/core/xsd/schema/current.txt
@@ -183,6 +183,7 @@ package com.android.xml.permission.configfile {
method public java.util.List<com.android.xml.permission.configfile.OemPermissions> getOemPermissions_optional();
method public java.util.List<com.android.xml.permission.configfile.Permission> getPermission_optional();
method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions> getPrivappPermissions_optional();
+ method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions> getSignaturePermissions_optional();
method public java.util.List<com.android.xml.permission.configfile.SplitPermission> getSplitPermission_optional();
method public java.util.List<com.android.xml.permission.configfile.SystemUserBlacklistedApp> getSystemUserBlacklistedApp_optional();
method public java.util.List<com.android.xml.permission.configfile.SystemUserWhitelistedApp> getSystemUserWhitelistedApp_optional();
@@ -209,6 +210,26 @@ package com.android.xml.permission.configfile {
method public void setName(String);
}
+ public class SignaturePermissions {
+ ctor public SignaturePermissions();
+ method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions.DenyPermission> getDenyPermission();
+ method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions.Permission> getPermission();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public static class SignaturePermissions.DenyPermission {
+ ctor public SignaturePermissions.DenyPermission();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public static class SignaturePermissions.Permission {
+ ctor public SignaturePermissions.Permission();
+ method public String getName();
+ method public void setName(String);
+ }
+
public class SplitPermission {
ctor public SplitPermission();
method public java.util.List<com.android.xml.permission.configfile.SplitPermission.Library> getLibrary();
diff --git a/core/xsd/vibrator/vibration/schema/current.txt b/core/xsd/vibrator/vibration/schema/current.txt
index 280b40516b7e..b4148d657b0d 100644
--- a/core/xsd/vibrator/vibration/schema/current.txt
+++ b/core/xsd/vibrator/vibration/schema/current.txt
@@ -15,12 +15,20 @@ package com.android.internal.vibrator.persistence {
enum_constant public static final com.android.internal.vibrator.persistence.PredefinedEffectName tick;
}
+ public enum PrimitiveDelayType {
+ method public String getRawName();
+ enum_constant public static final com.android.internal.vibrator.persistence.PrimitiveDelayType pause;
+ enum_constant public static final com.android.internal.vibrator.persistence.PrimitiveDelayType relative_start_offset;
+ }
+
public class PrimitiveEffect {
ctor public PrimitiveEffect();
method public java.math.BigInteger getDelayMs();
+ method public com.android.internal.vibrator.persistence.PrimitiveDelayType getDelayType();
method public com.android.internal.vibrator.persistence.PrimitiveEffectName getName();
method public float getScale();
method public void setDelayMs(java.math.BigInteger);
+ method public void setDelayType(com.android.internal.vibrator.persistence.PrimitiveDelayType);
method public void setName(com.android.internal.vibrator.persistence.PrimitiveEffectName);
method public void setScale(float);
}
diff --git a/core/xsd/vibrator/vibration/vibration-plus-hidden-apis.xsd b/core/xsd/vibrator/vibration/vibration-plus-hidden-apis.xsd
index 21a6facad242..910a9b700b5c 100644
--- a/core/xsd/vibrator/vibration/vibration-plus-hidden-apis.xsd
+++ b/core/xsd/vibrator/vibration/vibration-plus-hidden-apis.xsd
@@ -147,6 +147,7 @@
<xs:attribute name="name" type="PrimitiveEffectName" use="required"/>
<xs:attribute name="scale" type="PrimitiveScale"/>
<xs:attribute name="delayMs" type="xs:nonNegativeInteger"/>
+ <xs:attribute name="delayType" type="PrimitiveDelayType"/>
</xs:complexType>
<!-- Primitive names as defined by VibrationEffect.Composition.PRIMITIVE_* -->
@@ -171,4 +172,12 @@
</xs:restriction>
</xs:simpleType>
+ <!-- Primitive delay types VibrationEffect.Composition.DELAY_TYPE_* -->
+ <xs:simpleType name="PrimitiveDelayType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="pause"/>
+ <xs:enumeration value="relative_start_offset"/>
+ </xs:restriction>
+ </xs:simpleType>
+
</xs:schema>
diff --git a/core/xsd/vibrator/vibration/vibration.xsd b/core/xsd/vibrator/vibration/vibration.xsd
index d35d777d4450..3c8e01605659 100644
--- a/core/xsd/vibrator/vibration/vibration.xsd
+++ b/core/xsd/vibrator/vibration/vibration.xsd
@@ -124,6 +124,7 @@
<xs:attribute name="name" type="PrimitiveEffectName" use="required"/>
<xs:attribute name="scale" type="PrimitiveScale"/>
<xs:attribute name="delayMs" type="xs:nonNegativeInteger"/>
+ <xs:attribute name="delayType" type="PrimitiveDelayType"/>
</xs:complexType>
<!-- Primitive names as defined by VibrationEffect.Composition.PRIMITIVE_* -->
@@ -148,4 +149,12 @@
</xs:restriction>
</xs:simpleType>
+ <!-- Primitive delay types VibrationEffect.Composition.DELAY_TYPE_* -->
+ <xs:simpleType name="PrimitiveDelayType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="pause"/>
+ <xs:enumeration value="relative_start_offset"/>
+ </xs:restriction>
+ </xs:simpleType>
+
</xs:schema>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index af690f4449af..897fc543517e 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -677,8 +677,4 @@ applications that come with the platform
<permission name="android.permission.BATTERY_STATS"/>
<permission name="android.permission.ENTER_TRADE_IN_MODE"/>
</privapp-permissions>
-
- <privapp-permissions package="com.android.multiuser">
- <permission name="android.permission.MANAGE_USERS"/>
- </privapp-permissions>
</permissions>
diff --git a/graphics/java/android/graphics/RuntimeColorFilter.java b/graphics/java/android/graphics/RuntimeColorFilter.java
index d112f7153fca..a64acfe767a9 100644
--- a/graphics/java/android/graphics/RuntimeColorFilter.java
+++ b/graphics/java/android/graphics/RuntimeColorFilter.java
@@ -280,7 +280,8 @@ public class RuntimeColorFilter extends ColorFilter {
if (colorFilter == null) {
throw new NullPointerException("The colorFilter parameter must not be null");
}
- nativeUpdateChild(getNativeInstance(), filterName, colorFilter.getNativeInstance());
+ nativeUpdateInputColorFilter(getNativeInstance(), filterName,
+ colorFilter.getNativeInstance());
}
/**
@@ -318,5 +319,6 @@ public class RuntimeColorFilter extends ColorFilter {
long colorFilter, String uniformName, int value1, int value2, int value3,
int value4, int count);
private static native void nativeUpdateChild(long colorFilter, String childName, long child);
-
+ private static native void nativeUpdateInputColorFilter(long colorFilter, String childName,
+ long inputFilter);
}
diff --git a/graphics/java/android/graphics/RuntimeShader.java b/graphics/java/android/graphics/RuntimeShader.java
index 6316c1fb8b47..3543e991924e 100644
--- a/graphics/java/android/graphics/RuntimeShader.java
+++ b/graphics/java/android/graphics/RuntimeShader.java
@@ -264,6 +264,9 @@ public class RuntimeShader extends Shader {
* enable better heap tracking & tooling support
*/
private ArrayMap<String, Shader> mShaderUniforms = new ArrayMap<>();
+ private ArrayMap<String, ColorFilter> mColorFilterUniforms = new ArrayMap<>();
+ private ArrayMap<String, RuntimeXfermode> mXfermodeUniforms = new ArrayMap<>();
+
/**
* Creates a new RuntimeShader.
@@ -544,8 +547,10 @@ public class RuntimeShader extends Shader {
if (colorFilter == null) {
throw new NullPointerException("The colorFilter parameter must not be null");
}
- nativeUpdateChild(mNativeInstanceRuntimeShaderBuilder, filterName,
+ mColorFilterUniforms.put(filterName, colorFilter);
+ nativeUpdateColorFilter(mNativeInstanceRuntimeShaderBuilder, filterName,
colorFilter.getNativeInstance());
+ discardNativeInstance();
}
/**
@@ -563,8 +568,10 @@ public class RuntimeShader extends Shader {
if (xfermode == null) {
throw new NullPointerException("The xfermode parameter must not be null");
}
+ mXfermodeUniforms.put(xfermodeName, xfermode);
nativeUpdateChild(mNativeInstanceRuntimeShaderBuilder, xfermodeName,
xfermode.createNativeInstance());
+ discardNativeInstance();
}
@@ -594,6 +601,8 @@ public class RuntimeShader extends Shader {
int value4, int count);
private static native void nativeUpdateShader(
long shaderBuilder, String shaderName, long shader);
+ private static native void nativeUpdateColorFilter(
+ long shaderBuilder, String colorFilterName, long colorFilter);
private static native void nativeUpdateChild(
long shaderBuilder, String childName, long child);
}
diff --git a/graphics/java/android/graphics/RuntimeXfermode.java b/graphics/java/android/graphics/RuntimeXfermode.java
index 51d97a4b7487..c8a0b1a11339 100644
--- a/graphics/java/android/graphics/RuntimeXfermode.java
+++ b/graphics/java/android/graphics/RuntimeXfermode.java
@@ -285,7 +285,8 @@ public class RuntimeXfermode extends Xfermode {
if (colorFilter == null) {
throw new NullPointerException("The colorFilter parameter must not be null");
}
- nativeUpdateChild(mBuilderNativeInstance, filterName, colorFilter.getNativeInstance());
+ nativeUpdateColorFilter(mBuilderNativeInstance, filterName,
+ colorFilter.getNativeInstance());
}
/**
@@ -325,5 +326,6 @@ public class RuntimeXfermode extends Xfermode {
long builder, String uniformName, int value1, int value2, int value3,
int value4, int count);
private static native void nativeUpdateChild(long builder, String childName, long child);
+ private static native void nativeUpdateColorFilter(long builder, String childName, long filter);
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index 089613853555..5ea38431829e 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -30,8 +30,6 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
-import androidx.annotation.BinderThread;
-import androidx.annotation.GuardedBy;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -39,14 +37,12 @@ import androidx.window.common.layout.CommonFoldingFeature;
import androidx.window.common.layout.DisplayFoldFeatureCommon;
import com.android.internal.R;
-import com.android.window.flags.Flags;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
-import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
@@ -70,20 +66,8 @@ public final class DeviceStateManagerFoldingFeatureProducer
* "rear display". Concurrent mode for example is activated via public API and can be active in
* both the "open" and "half folded" device states.
*/
- // TODO: b/337820752 - Add @GuardedBy("mCurrentDeviceStateLock") after flag cleanup.
private DeviceState mCurrentDeviceState = INVALID_DEVICE_STATE;
- /**
- * Lock to synchronize access to {@link #mCurrentDeviceState}.
- *
- * <p>This lock is used to ensure thread-safety when accessing and modifying the
- * {@link #mCurrentDeviceState} field. It is acquired by both the binder thread (if
- * {@link Flags#wlinfoOncreate()} is enabled) and the main thread (if
- * {@link Flags#wlinfoOncreate()} is disabled) to prevent race conditions and
- * ensure data consistency.
- */
- private final Object mCurrentDeviceStateLock = new Object();
-
@NonNull
private final RawFoldingFeatureProducer mRawFoldSupplier;
@@ -95,15 +79,12 @@ public final class DeviceStateManagerFoldingFeatureProducer
// The GuardedBy analysis is intra-procedural, meaning it doesn’t consider the getData()
// implementation. See https://errorprone.info/bugpattern/GuardedBy for limitations.
@SuppressWarnings("GuardedBy")
- @BinderThread // When Flags.wlinfoOncreate() is enabled.
- @MainThread // When Flags.wlinfoOncreate() is disabled.
+ @MainThread
@Override
public void onDeviceStateChanged(@NonNull DeviceState state) {
- synchronized (mCurrentDeviceStateLock) {
- mCurrentDeviceState = state;
- mRawFoldSupplier.getData(DeviceStateManagerFoldingFeatureProducer.this
- ::notifyFoldingFeatureChangeLocked);
- }
+ mCurrentDeviceState = state;
+ mRawFoldSupplier.getData(DeviceStateManagerFoldingFeatureProducer.this
+ ::notifyFoldingFeatureChangeLocked);
}
};
@@ -115,10 +96,8 @@ public final class DeviceStateManagerFoldingFeatureProducer
new DeviceStateMapper(context, deviceStateManager.getSupportedDeviceStates());
if (!mDeviceStateMapper.isDeviceStateToPostureMapEmpty()) {
- final Executor executor =
- Flags.wlinfoOncreate() ? Runnable::run : context.getMainExecutor();
Objects.requireNonNull(deviceStateManager)
- .registerCallback(executor, mDeviceStateCallback);
+ .registerCallback(context.getMainExecutor(), mDeviceStateCallback);
}
}
@@ -145,21 +124,17 @@ public final class DeviceStateManagerFoldingFeatureProducer
@Override
protected void onListenersChanged() {
super.onListenersChanged();
- synchronized (mCurrentDeviceStateLock) {
- if (hasListeners()) {
- mRawFoldSupplier.addDataChangedCallback(this::notifyFoldingFeatureChangeLocked);
- } else {
- mCurrentDeviceState = INVALID_DEVICE_STATE;
- mRawFoldSupplier.removeDataChangedCallback(this::notifyFoldingFeatureChangeLocked);
- }
+ if (hasListeners()) {
+ mRawFoldSupplier.addDataChangedCallback(this::notifyFoldingFeatureChangeLocked);
+ } else {
+ mCurrentDeviceState = INVALID_DEVICE_STATE;
+ mRawFoldSupplier.removeDataChangedCallback(this::notifyFoldingFeatureChangeLocked);
}
}
@NonNull
private DeviceState getCurrentDeviceState() {
- synchronized (mCurrentDeviceStateLock) {
- return mCurrentDeviceState;
- }
+ return mCurrentDeviceState;
}
@NonNull
@@ -231,7 +206,6 @@ public final class DeviceStateManagerFoldingFeatureProducer
});
}
- @GuardedBy("mCurrentDeviceStateLock")
private void notifyFoldingFeatureChangeLocked(String displayFeaturesString) {
final DeviceState state = mCurrentDeviceState;
if (!mDeviceStateMapper.isDeviceStateValid(state)) {
@@ -252,29 +226,16 @@ public final class DeviceStateManagerFoldingFeatureProducer
return parseListFromString(displayFeaturesString, hingeState);
}
- /**
- * Internal class to map device states to corresponding postures.
- *
- * <p>This class encapsulates the logic for mapping device states to postures. The mapping is
- * immutable after initialization to ensure thread safety.
- */
+ /** Internal class to map device states to corresponding postures. */
private static class DeviceStateMapper {
/**
* Emulated device state
* {@link DeviceStateManager.DeviceStateCallback#onDeviceStateChanged(DeviceState)} to
* {@link CommonFoldingFeature.State} map.
- *
- * <p>This map must be immutable after initialization to ensure thread safety, as it may be
- * accessed from multiple threads. Modifications should only occur during object
- * construction.
*/
private final SparseIntArray mDeviceStateToPostureMap = new SparseIntArray();
- /**
- * The list of device states that are supported.
- *
- * <p>This list must be immutable after initialization to ensure thread safety.
- */
+ /** The list of device states that are supported. */
@NonNull
private final List<DeviceState> mSupportedStates;
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducerTest.kt b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducerTest.kt
index 90887a747a6f..fb01cd88158c 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducerTest.kt
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducerTest.kt
@@ -20,9 +20,6 @@ import android.content.Context
import android.content.res.Resources
import android.hardware.devicestate.DeviceState
import android.hardware.devicestate.DeviceStateManager
-import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
-import android.platform.test.flag.junit.SetFlagsRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.window.common.layout.CommonFoldingFeature
import androidx.window.common.layout.CommonFoldingFeature.COMMON_STATE_FLAT
@@ -34,15 +31,11 @@ import androidx.window.common.layout.DisplayFoldFeatureCommon
import androidx.window.common.layout.DisplayFoldFeatureCommon.DISPLAY_FOLD_FEATURE_PROPERTY_SUPPORTS_HALF_OPENED
import androidx.window.common.layout.DisplayFoldFeatureCommon.DISPLAY_FOLD_FEATURE_TYPE_SCREEN_FOLD_IN
import com.android.internal.R
-import com.android.window.flags.Flags
import com.google.common.truth.Truth.assertThat
import java.util.Optional
-import java.util.concurrent.Executor
import java.util.function.Consumer
-import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
@@ -60,9 +53,6 @@ import org.mockito.kotlin.verify
*/
@RunWith(AndroidJUnit4::class)
class DeviceStateManagerFoldingFeatureProducerTest {
- @get:Rule
- val setFlagsRule: SetFlagsRule = SetFlagsRule()
-
private val mMockDeviceStateManager = mock<DeviceStateManager>()
private val mMockResources = mock<Resources> {
on { getStringArray(R.array.config_device_state_postures) } doReturn DEVICE_STATE_POSTURES
@@ -79,8 +69,7 @@ class DeviceStateManagerFoldingFeatureProducerTest {
}
@Test
- @DisableFlags(Flags.FLAG_WLINFO_ONCREATE)
- fun testRegisterCallback_whenWlinfoOncreateIsDisabled_usesMainExecutor() {
+ fun testRegisterCallback_usesMainExecutor() {
DeviceStateManagerFoldingFeatureProducer(
mMockContext,
mRawFoldSupplier,
@@ -91,23 +80,6 @@ class DeviceStateManagerFoldingFeatureProducerTest {
}
@Test
- @EnableFlags(Flags.FLAG_WLINFO_ONCREATE)
- fun testRegisterCallback_whenWlinfoOncreateIsEnabled_usesRunnableRun() {
- val executorCaptor = ArgumentCaptor.forClass(Executor::class.java)
- val runnable = mock<Runnable>()
-
- DeviceStateManagerFoldingFeatureProducer(
- mMockContext,
- mRawFoldSupplier,
- mMockDeviceStateManager,
- )
-
- verify(mMockDeviceStateManager).registerCallback(executorCaptor.capture(), any())
- executorCaptor.value.execute(runnable)
- verify(runnable).run()
- }
-
- @Test
fun testGetCurrentData_validCurrentState_returnsFoldingFeatureWithState() {
val ffp = DeviceStateManagerFoldingFeatureProducer(
mMockContext,
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index a354bf78bb39..4c75ea4777da 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -182,6 +182,7 @@ android_library {
"kotlinx-coroutines-core",
"//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
"//frameworks/libs/systemui:iconloader_base",
+ "com_android_launcher3_flags_lib",
"com_android_wm_shell_flags_lib",
"PlatformAnimationLib",
"WindowManager-Shell-proto",
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
index 6ac36a3319c9..1bf6af8d1f6d 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
@@ -17,6 +17,7 @@
package com.android.wm.shell.bubbles.bar
import android.app.ActivityManager
+import android.content.ComponentName
import android.content.Context
import android.content.pm.ShortcutInfo
import android.graphics.Insets
@@ -24,6 +25,7 @@ import android.graphics.Rect
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
+import android.widget.FrameLayout
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -110,9 +112,9 @@ class BubbleBarExpandedViewTest {
regionSamplingProvider = TestRegionSamplingProvider()
- bubbleExpandedView = (inflater.inflate(
+ bubbleExpandedView = inflater.inflate(
R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */
- ) as BubbleBarExpandedView)
+ ) as BubbleBarExpandedView
bubbleExpandedView.initialize(
expandedViewManager,
positioner,
@@ -124,11 +126,11 @@ class BubbleBarExpandedViewTest {
regionSamplingProvider,
)
- getInstrumentation().runOnMainSync(Runnable {
+ getInstrumentation().runOnMainSync {
bubbleExpandedView.onAttachedToWindow()
// Helper should be created once attached to window
testableRegionSamplingHelper = regionSamplingProvider!!.helper
- })
+ }
bubble = Bubble(
"key",
@@ -254,6 +256,93 @@ class BubbleBarExpandedViewTest {
assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
}
+ @Test
+ fun animateExpansion_waitsUntilTaskCreated() {
+ var animated = false
+ bubbleExpandedView.animateExpansionWhenTaskViewVisible { animated = true }
+ assertThat(animated).isFalse()
+ bubbleExpandedView.onTaskCreated()
+ assertThat(animated).isTrue()
+ }
+
+ @Test
+ fun animateExpansion_taskViewAttachedAndVisible() {
+ val inflater = LayoutInflater.from(context)
+ val expandedView = inflater.inflate(
+ R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */
+ ) as BubbleBarExpandedView
+ val taskView = FakeBubbleTaskViewFactory().create()
+ val taskViewParent = FrameLayout(context)
+ taskViewParent.addView(taskView.taskView)
+ taskView.listener.onTaskCreated(666, ComponentName(context, "BubbleBarExpandedViewTest"))
+ assertThat(taskView.isVisible).isTrue()
+
+ expandedView.initialize(
+ expandedViewManager,
+ positioner,
+ BubbleLogger(uiEventLoggerFake),
+ false /* isOverflow */,
+ taskView,
+ mainExecutor,
+ bgExecutor,
+ regionSamplingProvider,
+ )
+
+ // the task view should be removed from its parent
+ assertThat(taskView.taskView.parent).isNull()
+
+ var animated = false
+ expandedView.animateExpansionWhenTaskViewVisible { animated = true }
+ assertThat(animated).isFalse()
+
+ // send an invisible signal to simulate the surface getting destroyed
+ expandedView.onContentVisibilityChanged(false)
+
+ // send a visible signal to simulate a new surface getting created
+ expandedView.onContentVisibilityChanged(true)
+
+ assertThat(taskView.taskView.parent).isEqualTo(expandedView)
+ assertThat(animated).isTrue()
+ }
+
+ @Test
+ fun animateExpansion_taskViewAttachedAndInvisible() {
+ val inflater = LayoutInflater.from(context)
+ val expandedView = inflater.inflate(
+ R.layout.bubble_bar_expanded_view, null, false /* attachToRoot */
+ ) as BubbleBarExpandedView
+ val taskView = FakeBubbleTaskViewFactory().create()
+ val taskViewParent = FrameLayout(context)
+ taskViewParent.addView(taskView.taskView)
+ taskView.listener.onTaskCreated(666, ComponentName(context, "BubbleBarExpandedViewTest"))
+ assertThat(taskView.isVisible).isTrue()
+ taskView.listener.onTaskVisibilityChanged(666, false)
+ assertThat(taskView.isVisible).isFalse()
+
+ expandedView.initialize(
+ expandedViewManager,
+ positioner,
+ BubbleLogger(uiEventLoggerFake),
+ false /* isOverflow */,
+ taskView,
+ mainExecutor,
+ bgExecutor,
+ regionSamplingProvider,
+ )
+
+ // the task view should be added to the expanded view
+ assertThat(taskView.taskView.parent).isEqualTo(expandedView)
+
+ var animated = false
+ expandedView.animateExpansionWhenTaskViewVisible { animated = true }
+ assertThat(animated).isFalse()
+
+ // send a visible signal to simulate a new surface getting created
+ expandedView.onContentVisibilityChanged(true)
+
+ assertThat(animated).isTrue()
+ }
+
private fun BubbleBarExpandedView.menuView(): BubbleBarMenuView {
return findViewByPredicate { it is BubbleBarMenuView }
}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
index 22597ac6ab67..7280f8aa07a6 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
@@ -253,6 +253,7 @@ class BubbleBarLayerViewTest {
getInstrumentation().runOnMainSync {
bubbleBarLayerView.showExpandedView(bubble)
+ bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true)
}
waitForExpandedViewAnimation()
@@ -276,6 +277,7 @@ class BubbleBarLayerViewTest {
getInstrumentation().runOnMainSync {
bubbleBarLayerView.showExpandedView(bubble)
+ bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true)
}
waitForExpandedViewAnimation()
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 37339307f5b0..7e5a82e640cc 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
@@ -39,6 +39,8 @@ import android.view.animation.DecelerateInterpolator
import android.view.animation.Interpolator
import android.view.animation.Transformation
import android.window.BackEvent
+import android.window.BackEvent.EDGE_LEFT
+import android.window.BackEvent.EDGE_RIGHT
import android.window.BackMotionEvent
import android.window.BackNavigationInfo
import android.window.BackProgressAnimator
@@ -50,6 +52,7 @@ import com.android.internal.jank.Cuj
import com.android.internal.policy.ScreenDecorationsUtils
import com.android.internal.policy.SystemBarUtils
import com.android.internal.protolog.ProtoLog
+import com.android.window.flags.Flags.predictiveBackTimestampApi
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.protolog.ShellProtoLogGroup
@@ -118,7 +121,9 @@ abstract class CrossActivityBackAnimation(
private val postCommitFlingSpring = SpringForce(SPRING_SCALE)
.setStiffness(SpringForce.STIFFNESS_LOW)
.setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
+ private var swipeEdge = EDGE_LEFT
protected var gestureProgress = 0f
+ private val velocityTracker = ProgressVelocityTracker()
/** Background color to be used during the animation, also see [getBackgroundColor] */
protected var customizedBackgroundColor = 0
@@ -175,6 +180,7 @@ abstract class CrossActivityBackAnimation(
)
return
}
+ swipeEdge = backMotionEvent.swipeEdge
triggerBack = backMotionEvent.triggerBack
initialTouchPos.set(backMotionEvent.touchX, backMotionEvent.touchY)
@@ -241,6 +247,9 @@ abstract class CrossActivityBackAnimation(
)
applyTransaction()
background.customizeStatusBarAppearance(currentClosingRect.top.toInt())
+ if (predictiveBackTimestampApi()) {
+ velocityTracker.addPosition(backEvent.frameTimeMillis, progress)
+ }
}
private fun getYOffset(centeredRect: RectF, touchY: Float): Float {
@@ -272,10 +281,19 @@ abstract class CrossActivityBackAnimation(
// kick off spring animation with the current velocity from the pre-commit phase, this
// affects the scaling of the closing and/or opening activity during post-commit
- val startVelocity =
- if (gestureProgress < 0.1f) -DEFAULT_FLING_VELOCITY else -velocity * SPRING_SCALE
+
+ var startVelocity = if (predictiveBackTimestampApi()) {
+ // pronounce fling animation more for gestures
+ val velocityFactor = if (swipeEdge == EDGE_LEFT || swipeEdge == EDGE_RIGHT) 2f else 1f
+ velocity * SPRING_SCALE * (1f - MAX_SCALE) * velocityFactor
+ } else {
+ velocity * SPRING_SCALE
+ }
+ if (gestureProgress < 0.1f) {
+ startVelocity = startVelocity.coerceAtLeast(DEFAULT_FLING_VELOCITY)
+ }
val flingAnimation = SpringAnimation(postCommitFlingScale, SPRING_SCALE)
- .setStartVelocity(startVelocity.coerceIn(-MAX_FLING_VELOCITY, 0f))
+ .setStartVelocity(-startVelocity.coerceIn(0f, MAX_FLING_VELOCITY))
.setStartValue(SPRING_SCALE)
.setSpring(postCommitFlingSpring)
flingAnimation.start()
@@ -338,6 +356,7 @@ abstract class CrossActivityBackAnimation(
lastPostCommitFlingScale = SPRING_SCALE
gestureProgress = 0f
triggerBack = false
+ velocityTracker.resetTracking()
}
protected fun applyTransform(
@@ -520,7 +539,11 @@ abstract class CrossActivityBackAnimation(
override fun onBackInvoked() {
triggerBack = true
progressAnimator.reset()
- onGestureCommitted(progressAnimator.velocity)
+ if (predictiveBackTimestampApi()) {
+ onGestureCommitted(velocityTracker.calculateVelocity())
+ } else {
+ onGestureCommitted(progressAnimator.velocity)
+ }
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
index dc50fdbd1af3..f48b3ffcd598 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
@@ -16,7 +16,6 @@
package com.android.wm.shell.back;
-import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static android.window.BackEvent.EDGE_RIGHT;
@@ -43,10 +42,8 @@ import android.util.TimeUtils;
import android.view.Choreographer;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
-import android.view.MotionEvent;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
-import android.view.VelocityTracker;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.window.BackEvent;
@@ -132,9 +129,8 @@ public class CrossTaskBackAnimation extends ShellBackAnimation {
private final SpringForce mPostCommitFlingSpring = new SpringForce(SPRING_SCALE)
.setStiffness(FLING_SPRING_STIFFNESS)
.setDampingRatio(1f);
- private final VelocityTracker mVelocityTracker = VelocityTracker.obtain();
+ private final ProgressVelocityTracker mVelocityTracker = new ProgressVelocityTracker();
private float mGestureProgress = 0f;
- private long mDownTime = 0L;
@Inject
public CrossTaskBackAnimation(Context context, BackAnimationBackground background,
@@ -316,8 +312,7 @@ public class CrossTaskBackAnimation extends ShellBackAnimation {
mClosingCurrentRect.setEmpty();
mInitialTouchPos.set(0, 0);
mGestureProgress = 0;
- mDownTime = 0;
- mVelocityTracker.clear();
+ mVelocityTracker.resetTracking();
if (mFinishCallback != null) {
try {
@@ -333,22 +328,13 @@ public class CrossTaskBackAnimation extends ShellBackAnimation {
private void onGestureProgress(@NonNull BackEvent backEvent) {
if (!mBackInProgress) {
mBackInProgress = true;
- mDownTime = backEvent.getFrameTimeMillis();
}
float progress = backEvent.getProgress();
mTouchPos.set(backEvent.getTouchX(), backEvent.getTouchY());
float interpolatedProgress = getInterpolatedProgress(progress);
if (predictiveBackTimestampApi()) {
- mVelocityTracker.addMovement(
- MotionEvent.obtain(
- /* downTime */ mDownTime,
- /* eventTime */ backEvent.getFrameTimeMillis(),
- /* action */ ACTION_MOVE,
- /* x */ interpolatedProgress * SPRING_SCALE,
- /* y */ 0f,
- /* metaState */ 0
- )
- );
+ mVelocityTracker.addPosition(backEvent.getFrameTimeMillis(),
+ interpolatedProgress * SPRING_SCALE);
}
updateGestureBackProgress(interpolatedProgress, backEvent);
}
@@ -362,9 +348,8 @@ public class CrossTaskBackAnimation extends ShellBackAnimation {
if (predictiveBackTimestampApi()) {
// kick off spring animation with the current velocity from the pre-commit phase, this
// affects the scaling of the closing and/or opening task during post-commit
- mVelocityTracker.computeCurrentVelocity(1000);
float startVelocity = mGestureProgress < 0.1f
- ? -DEFAULT_FLING_VELOCITY : -mVelocityTracker.getXVelocity();
+ ? -DEFAULT_FLING_VELOCITY : -mVelocityTracker.calculateVelocity();
SpringAnimation flingAnimation =
new SpringAnimation(mPostCommitFlingScale, SPRING_SCALE)
.setStartVelocity(Math.max(-MAX_FLING_VELOCITY, Math.min(0f, startVelocity)))
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ProgressVelocityTracker.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ProgressVelocityTracker.kt
new file mode 100644
index 000000000000..6bbda0fd7b19
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ProgressVelocityTracker.kt
@@ -0,0 +1,50 @@
+/*
+ * 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.back
+
+import android.view.MotionEvent
+import android.view.VelocityTracker
+
+internal class ProgressVelocityTracker {
+ private val velocityTracker: VelocityTracker = VelocityTracker.obtain()
+ private var downTime = -1L
+
+ fun addPosition(timeMillis: Long, position: Float) {
+ if (downTime == -1L) downTime = timeMillis
+ velocityTracker.addMovement(
+ MotionEvent.obtain(
+ /* downTime */ downTime,
+ /* eventTime */ timeMillis,
+ /* action */ MotionEvent.ACTION_MOVE,
+ /* x */ position,
+ /* y */ 0f,
+ /* metaState */0
+ )
+ )
+ }
+
+ /** calculates current velocity (unit: progress per second) */
+ fun calculateVelocity(): Float {
+ velocityTracker.computeCurrentVelocity(1000)
+ return velocityTracker.xVelocity
+ }
+
+ fun resetTracking() {
+ velocityTracker.clear()
+ downTime = -1L
+ }
+} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 294569190f68..dc2025bb2dce 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -898,7 +898,10 @@ public class BubbleData {
Bubble oldest = mOverflowBubbles.get(mOverflowBubbles.size() - 1);
ProtoLog.d(WM_SHELL_BUBBLES, "overflow full, remove=%s", oldest.getKey());
mStateChange.bubbleRemoved(oldest, Bubbles.DISMISS_OVERFLOW_MAX_REACHED);
- mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED);
+ if (!mPositioner.isShowingInBubbleBar()) {
+ // Only logged for bubbles in stack view
+ mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED);
+ }
mOverflowBubbles.remove(oldest);
mStateChange.removedOverflowBubble = oldest;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt
index 68fc0c99abee..a517a2d550b9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskView.kt
@@ -42,6 +42,16 @@ class BubbleTaskView(val taskView: TaskView, executor: Executor) {
var componentName: ComponentName? = null
private set
+ /**
+ * Whether the task view is visible and has a surface. Note that this does not check the alpha
+ * value of the task view.
+ *
+ * When this is `true` it is safe to start showing the task view. Otherwise if this is `false`
+ * callers should wait for it to be visible which will be indicated either by a call to
+ * [TaskView.Listener.onTaskCreated] or [TaskView.Listener.onTaskVisibilityChanged]. */
+ var isVisible = false
+ private set
+
/** [TaskView.Listener] for users of this class. */
var delegateListener: TaskView.Listener? = null
@@ -61,9 +71,12 @@ class BubbleTaskView(val taskView: TaskView, executor: Executor) {
this@BubbleTaskView.taskId = taskId
isCreated = true
componentName = name
+ // when the task is created it is visible
+ isVisible = true
}
override fun onTaskVisibilityChanged(taskId: Int, visible: Boolean) {
+ this@BubbleTaskView.isVisible = visible
delegateListener?.onTaskVisibilityChanged(taskId, visible)
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
index 74c3748dccaf..a313bd004a51 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
@@ -161,6 +161,7 @@ public class BubbleBarAnimationHelper {
updateExpandedView();
bbev.setAnimating(true);
+ bbev.setSurfaceZOrderedOnTop(true);
bbev.setContentVisibility(false);
bbev.setAlpha(0f);
bbev.setTaskViewAlpha(0f);
@@ -171,28 +172,29 @@ public class BubbleBarAnimationHelper {
bbev.setAnimationMatrix(mExpandedViewContainerMatrix);
- mExpandedViewAlphaAnimator.start();
-
- PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel();
- PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
- .spring(AnimatableScaleMatrix.SCALE_X,
- AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
- mScaleInSpringConfig)
- .spring(AnimatableScaleMatrix.SCALE_Y,
- AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
- mScaleInSpringConfig)
- .addUpdateListener((target, values) -> {
- bbev.setAnimationMatrix(mExpandedViewContainerMatrix);
- })
- .withEndActions(() -> {
- bbev.setAnimationMatrix(null);
- updateExpandedView();
- bbev.setSurfaceZOrderedOnTop(false);
- if (afterAnimation != null) {
- afterAnimation.run();
- }
- })
- .start();
+ bbev.animateExpansionWhenTaskViewVisible(() -> {
+ mExpandedViewAlphaAnimator.start();
+
+ PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel();
+ PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
+ .spring(AnimatableScaleMatrix.SCALE_X,
+ AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
+ mScaleInSpringConfig)
+ .spring(AnimatableScaleMatrix.SCALE_Y,
+ AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f),
+ mScaleInSpringConfig)
+ .addUpdateListener((target, values) -> {
+ bbev.setAnimationMatrix(mExpandedViewContainerMatrix);
+ })
+ .withEndActions(() -> {
+ bbev.setAnimationMatrix(null);
+ updateExpandedView();
+ if (afterAnimation != null) {
+ afterAnimation.run();
+ }
+ })
+ .start();
+ });
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
index 3764bcd42ac6..ed49417ad3bd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java
@@ -131,6 +131,11 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
/** Current corner radius */
private float mCurrentCornerRadius = 0f;
+ /** A runnable to start the expansion animation as soon as the task view is made visible. */
+ @Nullable
+ private Runnable mAnimateExpansion = null;
+ private TaskViewVisibilityState mVisibilityState = TaskViewVisibilityState.INVISIBLE;
+
/**
* Whether we want the {@code TaskView}'s content to be visible (alpha = 1f). If
* {@link #mIsAnimating} is true, this may not reflect the {@code TaskView}'s actual alpha
@@ -140,6 +145,18 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
private boolean mIsAnimating;
private boolean mIsDragging;
+ /** An enum value that tracks the visibility state of the task view */
+ private enum TaskViewVisibilityState {
+ /** The task view is going away, and we're waiting for the surface to be destroyed. */
+ PENDING_INVISIBLE,
+ /** The task view is invisible and does not have a surface. */
+ INVISIBLE,
+ /** The task view is in the process of being added to a surface. */
+ PENDING_VISIBLE,
+ /** The task view is visible and has a surface. */
+ VISIBLE
+ }
+
public BubbleBarExpandedView(Context context) {
this(context, null);
}
@@ -206,16 +223,27 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
mBubbleTaskViewHelper = new BubbleTaskViewHelper(mContext, expandedViewManager,
/* listener= */ this, bubbleTaskView,
/* viewParent= */ this);
+
+ // if the task view is already attached to a parent we need to remove it
if (mTaskView.getParent() != null) {
+ // it's possible that the task view is visible, e.g. if we're unfolding, in which
+ // case removing it will trigger a visibility change. we have to wait for that
+ // signal before we can add it to this expanded view, otherwise the signal will be
+ // incorrect because the task view will have a surface.
+ // if the task view is not visible, then it has no surface and removing it will not
+ // trigger any visibility change signals.
+ if (bubbleTaskView.isVisible()) {
+ mVisibilityState = TaskViewVisibilityState.PENDING_INVISIBLE;
+ }
((ViewGroup) mTaskView.getParent()).removeView(mTaskView);
}
- FrameLayout.LayoutParams lp =
- new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
- addView(mTaskView, lp);
- mTaskView.setEnableSurfaceClipping(true);
- mTaskView.setCornerRadius(mCurrentCornerRadius);
- mTaskView.setVisibility(VISIBLE);
- mTaskView.setCaptionInsets(Insets.of(0, mCaptionHeight, 0, 0));
+
+ // if we're invisible it's safe to setup the task view and then await on the visibility
+ // signal.
+ if (mVisibilityState == TaskViewVisibilityState.INVISIBLE) {
+ mVisibilityState = TaskViewVisibilityState.PENDING_VISIBLE;
+ setupTaskView();
+ }
// Handle view needs to draw on top of task view.
bringChildToFront(mHandleView);
@@ -269,6 +297,16 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
});
}
+ private void setupTaskView() {
+ FrameLayout.LayoutParams lp =
+ new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
+ addView(mTaskView, lp);
+ mTaskView.setEnableSurfaceClipping(true);
+ mTaskView.setCornerRadius(mCurrentCornerRadius);
+ mTaskView.setVisibility(VISIBLE);
+ mTaskView.setCaptionInsets(Insets.of(0, mCaptionHeight, 0, 0));
+ }
+
public BubbleBarHandleView getHandleView() {
return mHandleView;
}
@@ -326,15 +364,28 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
@Override
public void onTaskCreated() {
- setContentVisibility(true);
+ if (mTaskView != null) {
+ mTaskView.setAlpha(0);
+ }
if (mListener != null) {
mListener.onTaskCreated();
}
+ // when the task is created we're visible
+ onTaskViewVisible();
}
@Override
public void onContentVisibilityChanged(boolean visible) {
- setContentVisibility(visible);
+ if (mVisibilityState == TaskViewVisibilityState.PENDING_INVISIBLE && !visible) {
+ // the surface is now destroyed. set up the task view and wait for the visibility
+ // signal.
+ mVisibilityState = TaskViewVisibilityState.PENDING_VISIBLE;
+ setupTaskView();
+ return;
+ }
+ if (visible) {
+ onTaskViewVisible();
+ }
}
@Override
@@ -350,6 +401,25 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView
mListener.onBackPressed();
}
+ void animateExpansionWhenTaskViewVisible(Runnable animateExpansion) {
+ if (mVisibilityState == TaskViewVisibilityState.VISIBLE || mIsOverflow) {
+ animateExpansion.run();
+ } else {
+ mAnimateExpansion = animateExpansion;
+ }
+ }
+
+ private void onTaskViewVisible() {
+ // if we're waiting to be visible, start the expansion animation if it's pending.
+ if (mVisibilityState == TaskViewVisibilityState.PENDING_VISIBLE) {
+ mVisibilityState = TaskViewVisibilityState.VISIBLE;
+ if (mAnimateExpansion != null) {
+ mAnimateExpansion.run();
+ mAnimateExpansion = null;
+ }
+ }
+ }
+
/**
* Set whether this view is currently being dragged.
*
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
index 9abf0f678179..de5c834f3120 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java
@@ -33,6 +33,9 @@ public interface TaskStackListenerCallback {
default void onRecentTaskListFrozenChanged(boolean frozen) { }
+ /** A task is removed from recents as a result of another task being added to recent tasks. */
+ default void onRecentTaskRemovedForAddTask(int taskId) { }
+
@BinderThread
default void onTaskStackChangedBackground() { }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java
index d8859bac471f..4e1dec60d956 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerImpl.java
@@ -59,6 +59,7 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler.
private static final int ON_TASK_LIST_FROZEN_UNFROZEN = 18;
private static final int ON_TASK_DESCRIPTION_CHANGED = 19;
private static final int ON_ACTIVITY_ROTATION = 20;
+ private static final int ON_RECENT_TASK_REMOVED_FOR_ADD_TASK = 21;
/**
* List of {@link TaskStackListenerCallback} registered from {@link #addListener}.
@@ -132,6 +133,11 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler.
}
@Override
+ public void onRecentTaskRemovedForAddTask(int taskId) {
+ mMainHandler.obtainMessage(ON_RECENT_TASK_REMOVED_FOR_ADD_TASK, taskId).sendToTarget();
+ }
+
+ @Override
public void onTaskStackChanged() {
// Call the task changed callback for the non-ui thread listeners first. Copy to a set
// of temp listeners so that we don't lock on mTaskStackListeners while calling all the
@@ -408,6 +414,13 @@ public class TaskStackListenerImpl extends TaskStackListener implements Handler.
}
break;
}
+ case ON_RECENT_TASK_REMOVED_FOR_ADD_TASK: {
+ final int taskId = (int) msg.obj;
+ for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+ mTaskStackListeners.get(i).onRecentTaskRemovedForAddTask(taskId);
+ }
+ break;
+ }
case ON_TASK_DESCRIPTION_CHANGED: {
final ActivityManager.RunningTaskInfo
info = (ActivityManager.RunningTaskInfo) msg.obj;
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 fbf68ff97f08..0f636588476a 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
@@ -29,6 +29,7 @@ import android.annotation.Nullable;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.UserManager;
@@ -702,6 +703,7 @@ public abstract class WMShellModule {
InputManager inputManager,
FocusTransitionObserver focusTransitionObserver,
DesktopModeEventLogger desktopModeEventLogger,
+ DesktopModeUiEventLogger desktopModeUiEventLogger,
DesktopTilingDecorViewModel desktopTilingDecorViewModel) {
return new DesktopTasksController(
context,
@@ -732,6 +734,7 @@ public abstract class WMShellModule {
interactionJankMonitor,
mainHandler,
desktopModeEventLogger,
+ desktopModeUiEventLogger,
desktopTilingDecorViewModel);
}
@@ -893,7 +896,8 @@ public abstract class WMShellModule {
WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
FocusTransitionObserver focusTransitionObserver,
- DesktopModeEventLogger desktopModeEventLogger
+ DesktopModeEventLogger desktopModeEventLogger,
+ DesktopModeUiEventLogger desktopModeUiEventLogger
) {
if (!DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(context)) {
return Optional.empty();
@@ -906,7 +910,7 @@ public abstract class WMShellModule {
assistContentRequester, multiInstanceHelper, desktopTasksLimiter,
appHandleEducationController, appToWebEducationController,
windowDecorCaptionHandleRepository, activityOrientationChangeHandler,
- focusTransitionObserver, desktopModeEventLogger));
+ focusTransitionObserver, desktopModeEventLogger, desktopModeUiEventLogger));
}
@WMSingleton
@@ -1234,9 +1238,10 @@ public abstract class WMShellModule {
@WMSingleton
@Provides
static DesktopModeUiEventLogger provideDesktopUiEventLogger(
- UiEventLogger uiEventLogger
+ UiEventLogger uiEventLogger,
+ PackageManager packageManager
) {
- return new DesktopModeUiEventLogger(uiEventLogger);
+ return new DesktopModeUiEventLogger(uiEventLogger, packageManager);
}
//
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
index b4eac7a7b2d3..dc23128b7b2a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
@@ -446,6 +446,7 @@ class DesktopModeEventLogger {
val displayArea: Int?,
)
+ @JvmStatic
fun getInputMethodFromMotionEvent(e: MotionEvent?): InputMethod {
if (e == null) return InputMethod.UNKNOWN_INPUT_METHOD
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
index 114563aa18bb..6cb23b81f1e4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandler.kt
@@ -94,7 +94,7 @@ class DesktopModeKeyGestureHandler(
desktopTasksController.get().toggleDesktopTaskSize(
it,
ResizeTrigger.MAXIMIZE_MENU,
- null,
+ DesktopModeEventLogger.Companion.InputMethod.KEYBOARD,
)
}
return true
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
index dff56c13e03a..d0e01625a3aa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLogger.kt
@@ -16,6 +16,8 @@
package com.android.wm.shell.desktopmode
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.pm.PackageManager
import com.android.internal.logging.InstanceId
import com.android.internal.logging.InstanceIdSequence
import com.android.internal.logging.UiEvent
@@ -27,6 +29,7 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
/** Log Aster UIEvents for desktop windowing mode. */
class DesktopModeUiEventLogger(
private val uiEventLogger: UiEventLogger,
+ private val packageManager: PackageManager,
) {
private val instanceIdSequence = InstanceIdSequence(Integer.MAX_VALUE)
@@ -45,6 +48,17 @@ class DesktopModeUiEventLogger(
uiEventLogger.log(event, uid, packageName)
}
+ /** Logs an event for a CUI on a particular task. */
+ fun log(taskInfo: RunningTaskInfo, event: DesktopUiEventEnum) {
+ val packageName = taskInfo.baseActivity?.packageName
+ if (packageName == null) {
+ logD("Skip logging due to null base activity")
+ return
+ }
+ val uid = getUid(packageName, taskInfo.userId)
+ log(uid, packageName, event)
+ }
+
/** Retrieves a new instance id for a new interaction. */
fun getNewInstanceId(): InstanceId = instanceIdSequence.newInstanceId()
@@ -70,6 +84,12 @@ class DesktopModeUiEventLogger(
uiEventLogger.logWithInstanceId(event, uid, packageName, instanceId)
}
+ private fun getUid(packageName: String, userId: Int): Int = try {
+ packageManager.getApplicationInfoAsUser(packageName, /* flags= */ 0, userId).uid
+ } catch (e: PackageManager.NameNotFoundException) {
+ INVALID_PACKAGE_UID
+ }
+
private fun logD(msg: String, vararg arguments: Any?) {
ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
}
@@ -84,12 +104,33 @@ class DesktopModeUiEventLogger(
@UiEvent(doc = "Tap on the window header maximize button in desktop windowing mode")
DESKTOP_WINDOW_MAXIMIZE_BUTTON_TAP(1723),
@UiEvent(doc = "Double tap on window header to maximize it in desktop windowing mode")
- DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_MAXIMIZE(1724);
+ DESKTOP_WINDOW_HEADER_DOUBLE_TAP_TO_MAXIMIZE(1724),
+ @UiEvent(doc = "Tap on the window Handle to open the Handle Menu")
+ DESKTOP_WINDOW_APP_HANDLE_TAP(1998),
+ @UiEvent(doc = "Tap on the desktop mode option under app handle menu")
+ DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_DESKTOP_MODE(1999),
+ @UiEvent(doc = "Tap on the split screen option under app handle menu")
+ DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_SPLIT_SCREEN(2000),
+ @UiEvent(doc = "Tap on the full screen option under app handle menu")
+ DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_FULL_SCREEN(2001),
+ @UiEvent(doc = "When user successfully drags the app handle to desktop mode")
+ DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_DESKTOP_MODE(2002),
+ @UiEvent(doc = "When user successfully drags the app handle to split screen")
+ DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_SPLIT_SCREEN(2003),
+ @UiEvent(doc = "When user successfully drags the app handle to full screen")
+ DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_FULL_SCREEN(2004),
+ @UiEvent(doc = "Drag the window header to the top to switch to full screen mode")
+ DESKTOP_WINDOW_APP_HEADER_DRAG_TO_FULL_SCREEN(2005),
+ @UiEvent(doc = "Drag the window header to an edge to tile it to the left side")
+ DESKTOP_WINDOW_APP_HEADER_DRAG_TO_TILE_TO_LEFT(2006),
+ @UiEvent(doc = "Drag the window header to an edge to tile it to the right side")
+ DESKTOP_WINDOW_APP_HEADER_DRAG_TO_TILE_TO_RIGHT(2007);
override fun getId(): Int = mId
}
companion object {
private const val TAG = "DesktopModeUiEventLogger"
+ private const val INVALID_PACKAGE_UID = -1
}
}
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 ccbc9204ad9d..3e3dd74ae4b4 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
@@ -130,6 +130,7 @@ import java.util.concurrent.Executor
import java.util.function.Consumer
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.InputMethod
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum
import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.Companion.DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS
import com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION
import com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler.FULLSCREEN_ANIMATION_DURATION
@@ -166,6 +167,7 @@ class DesktopTasksController(
private val interactionJankMonitor: InteractionJankMonitor,
@ShellMainThread private val handler: Handler,
private val desktopModeEventLogger: DesktopModeEventLogger,
+ private val desktopModeUiEventLogger: DesktopModeUiEventLogger,
private val desktopTilingDecorViewModel: DesktopTilingDecorViewModel,
) :
RemoteCallable<DesktopTasksController>,
@@ -819,12 +821,12 @@ class DesktopTasksController(
fun toggleDesktopTaskSize(
taskInfo: RunningTaskInfo,
resizeTrigger: ResizeTrigger,
- motionEvent: MotionEvent?,
+ inputMethod: InputMethod,
) {
val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
desktopModeEventLogger.logTaskResizingStarted(
resizeTrigger,
- DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
+ inputMethod,
taskInfo,
currentTaskBounds.width(),
currentTaskBounds.height(),
@@ -877,7 +879,7 @@ class DesktopTasksController(
taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(doesAnyTaskRequireTaskbarRounding)
val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
desktopModeEventLogger.logTaskResizingEnded(
- resizeTrigger, DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent),
+ resizeTrigger, inputMethod,
taskInfo, destinationBounds.width(),
destinationBounds.height(), displayController
)
@@ -909,7 +911,11 @@ class DesktopTasksController(
return
}
- toggleDesktopTaskSize(taskInfo, ResizeTrigger.DRAG_TO_TOP_RESIZE_TRIGGER, motionEvent)
+ toggleDesktopTaskSize(
+ taskInfo,
+ ResizeTrigger.DRAG_TO_TOP_RESIZE_TRIGGER,
+ DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent)
+ )
}
private fun getMaximizeBounds(taskInfo: RunningTaskInfo, stableBounds: Rect): Rect {
@@ -2083,6 +2089,10 @@ class DesktopTasksController(
if (DesktopModeStatus.shouldMaximizeWhenDragToTopEdge(context)) {
dragToMaximizeDesktopTask(taskInfo, taskSurface, currentDragBounds, motionEvent)
} else {
+ desktopModeUiEventLogger.log(
+ taskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HEADER_DRAG_TO_FULL_SCREEN
+ )
moveToFullscreenWithAnimation(
taskInfo,
position,
@@ -2091,6 +2101,10 @@ class DesktopTasksController(
}
}
IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+ desktopModeUiEventLogger.log(
+ taskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HEADER_DRAG_TO_TILE_TO_LEFT
+ )
handleSnapResizingTaskOnDrag(
taskInfo,
SnapPosition.LEFT,
@@ -2102,6 +2116,10 @@ class DesktopTasksController(
)
}
IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+ desktopModeUiEventLogger.log(
+ taskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HEADER_DRAG_TO_TILE_TO_RIGHT
+ )
handleSnapResizingTaskOnDrag(
taskInfo,
SnapPosition.RIGHT,
@@ -2188,16 +2206,32 @@ class DesktopTasksController(
// Start a new jank interaction for the drag release to desktop window animation.
interactionJankMonitor.begin(taskSurface, context, handler,
CUJ_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG_RELEASE, "to_desktop")
+ desktopModeUiEventLogger.log(
+ taskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_DESKTOP_MODE
+ )
finalizeDragToDesktop(taskInfo)
}
IndicatorType.NO_INDICATOR,
IndicatorType.TO_FULLSCREEN_INDICATOR -> {
+ desktopModeUiEventLogger.log(
+ taskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_FULL_SCREEN
+ )
cancelDragToDesktop(taskInfo)
}
IndicatorType.TO_SPLIT_LEFT_INDICATOR -> {
+ desktopModeUiEventLogger.log(
+ taskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_SPLIT_SCREEN
+ )
requestSplit(taskInfo, leftOrTop = true)
}
IndicatorType.TO_SPLIT_RIGHT_INDICATOR -> {
+ desktopModeUiEventLogger.log(
+ taskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_DRAG_TO_SPLIT_SCREEN
+ )
requestSplit(taskInfo, leftOrTop = false)
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
index e835b2fec232..909a06604382 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
@@ -17,12 +17,10 @@
package com.android.wm.shell.desktopmode
import android.app.Activity
-import android.app.ActivityManager
+import android.app.TaskInfo
import android.content.ComponentName
import android.os.Bundle
import android.view.WindowManager
-import com.android.internal.protolog.ProtoLog
-import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
/**
* A transparent activity used in the desktop mode to show the wallpaper under the freeform windows.
@@ -42,11 +40,12 @@ class DesktopWallpaperActivity : Activity() {
companion object {
private const val SYSTEM_UI_PACKAGE_NAME = "com.android.systemui"
- private val wallpaperActivityComponent =
+ @JvmStatic
+ val wallpaperActivityComponent =
ComponentName(SYSTEM_UI_PACKAGE_NAME, DesktopWallpaperActivity::class.java.name)
@JvmStatic
- fun isWallpaperTask(taskInfo: ActivityManager.RunningTaskInfo) =
+ fun isWallpaperTask(taskInfo: TaskInfo) =
taskInfo.baseIntent.component?.let(::isWallpaperComponent) ?: false
@JvmStatic
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
index e01c448be8e5..de9c79ab34fd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationController.kt
@@ -82,9 +82,9 @@ class AppHandleEducationController(
runIfEducationFeatureEnabled {
applicationCoroutineScope.launch {
// Central block handling the app handle's educational flow end-to-end.
- isEducationViewedFlow()
- .flatMapLatest { isEducationViewed ->
- if (isEducationViewed) {
+ isAppHandleHintViewedFlow()
+ .flatMapLatest { isAppHandleHintViewed ->
+ if (isAppHandleHintViewed) {
// If the education is viewed then return emptyFlow() that completes immediately.
// This will help us to not listen to [captionHandleStateFlow] after the education
// has been viewed already.
@@ -106,12 +106,12 @@ class AppHandleEducationController(
showEducation(captionState, tooltipColorScheme)
// After showing first tooltip, mark education as viewed
- appHandleEducationDatastoreRepository.updateEducationViewedTimestampMillis(true)
+ appHandleEducationDatastoreRepository.updateAppHandleHintViewedTimestampMillis(true)
}
}
applicationCoroutineScope.launch {
- if (isFeatureUsed()) return@launch
+ if (isAppHandleHintUsed()) return@launch
windowDecorCaptionHandleRepository.captionStateFlow
.filter { captionState ->
captionState is CaptionState.AppHandle && captionState.isHandleMenuExpanded
@@ -119,8 +119,8 @@ class AppHandleEducationController(
.take(1)
.flowOn(backgroundDispatcher)
.collect {
- // If user expands app handle, mark user has used the feature
- appHandleEducationDatastoreRepository.updateFeatureUsedTimestampMillis(true)
+ // If user expands app handle, mark user has used the app handle hint
+ appHandleEducationDatastoreRepository.updateAppHandleHintUsedTimestampMillis(true)
}
}
}
@@ -323,25 +323,25 @@ class AppHandleEducationController(
}
/**
- * Listens to the changes to [WindowingEducationProto#hasEducationViewedTimestampMillis()] in
+ * Listens to the changes to [WindowingEducationProto#hasAppHandleHintViewedTimestampMillis()] in
* datastore proto object.
*
* If [SHOULD_OVERRIDE_EDUCATION_CONDITIONS] is true, this flow will always emit false. That means
- * it will emit education has not been viewed yet always.
+ * it will always emit app handle hint has not been viewed yet.
*/
- private fun isEducationViewedFlow(): Flow<Boolean> =
+ private fun isAppHandleHintViewedFlow(): Flow<Boolean> =
appHandleEducationDatastoreRepository.dataStoreFlow
.map { preferences ->
- preferences.hasEducationViewedTimestampMillis() && !SHOULD_OVERRIDE_EDUCATION_CONDITIONS
+ preferences.hasAppHandleHintViewedTimestampMillis() && !SHOULD_OVERRIDE_EDUCATION_CONDITIONS
}
.distinctUntilChanged()
/**
- * Listens to the changes to [WindowingEducationProto#hasFeatureUsedTimestampMillis()] in
+ * Listens to the changes to [WindowingEducationProto#hasAppHandleHintUsedTimestampMillis()] in
* datastore proto object.
*/
- private suspend fun isFeatureUsed(): Boolean =
- appHandleEducationDatastoreRepository.dataStoreFlow.first().hasFeatureUsedTimestampMillis()
+ private suspend fun isAppHandleHintUsed(): Boolean =
+ appHandleEducationDatastoreRepository.dataStoreFlow.first().hasAppHandleHintUsedTimestampMillis()
private fun getSize(@DimenRes resourceId: Int): Int {
if (resourceId == Resources.ID_NULL) return 0
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilter.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilter.kt
index 144370d76060..7a7829334fb6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilter.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilter.kt
@@ -54,8 +54,8 @@ class AppHandleEducationFilter(
return isFocusAppInAllowlist(focusAppPackageName) &&
!isOtherEducationShowing() &&
hasSufficientTimeSinceSetup() &&
- !isEducationViewedBefore(windowingEducationProto) &&
- !isFeatureUsedBefore(windowingEducationProto) &&
+ !isAppHandleHintViewedBefore(windowingEducationProto) &&
+ !isAppHandleHintUsedBefore(windowingEducationProto) &&
hasMinAppUsage(windowingEducationProto, focusAppPackageName)
}
@@ -76,11 +76,11 @@ class AppHandleEducationFilter(
convertIntegerResourceToDuration(
R.integer.desktop_windowing_education_required_time_since_setup_seconds)
- private fun isEducationViewedBefore(windowingEducationProto: WindowingEducationProto): Boolean =
- windowingEducationProto.hasEducationViewedTimestampMillis()
+ private fun isAppHandleHintViewedBefore(windowingEducationProto: WindowingEducationProto): Boolean =
+ windowingEducationProto.hasAppHandleHintViewedTimestampMillis()
- private fun isFeatureUsedBefore(windowingEducationProto: WindowingEducationProto): Boolean =
- windowingEducationProto.hasFeatureUsedTimestampMillis()
+ private fun isAppHandleHintUsedBefore(windowingEducationProto: WindowingEducationProto): Boolean =
+ windowingEducationProto.hasAppHandleHintUsedTimestampMillis()
private suspend fun hasMinAppUsage(
windowingEducationProto: WindowingEducationProto,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt
index d21b208df482..5e0c0007e2eb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/AppHandleEducationDatastoreRepository.kt
@@ -71,32 +71,34 @@ constructor(private val dataStore: DataStore<WindowingEducationProto>) {
suspend fun windowingEducationProto(): WindowingEducationProto = dataStoreFlow.first()
/**
- * Updates [WindowingEducationProto.educationViewedTimestampMillis_] field in datastore with
- * current timestamp if [isViewed] is true, if not then clears the field.
+ * Updates [WindowingEducationProto.appHandleHintViewedTimestampMillis_] field
+ * in datastore with current timestamp if [isViewed] is true, if not then
+ * clears the field.
*/
- suspend fun updateEducationViewedTimestampMillis(isViewed: Boolean) {
+ suspend fun updateAppHandleHintViewedTimestampMillis(isViewed: Boolean) {
dataStore.updateData { preferences ->
if (isViewed) {
preferences
.toBuilder()
- .setEducationViewedTimestampMillis(System.currentTimeMillis())
+ .setAppHandleHintViewedTimestampMillis(System.currentTimeMillis())
.build()
} else {
- preferences.toBuilder().clearEducationViewedTimestampMillis().build()
+ preferences.toBuilder().clearAppHandleHintViewedTimestampMillis().build()
}
}
}
/**
- * Updates [WindowingEducationProto.featureUsedTimestampMillis_] field in datastore with current
- * timestamp if [isViewed] is true, if not then clears the field.
+ * Updates [WindowingEducationProto.appHandleHintUsedTimestampMillis_] field
+ * in datastore with current timestamp if [isViewed] is true, if not then
+ * clears the field.
*/
- suspend fun updateFeatureUsedTimestampMillis(isViewed: Boolean) {
+ suspend fun updateAppHandleHintUsedTimestampMillis(isViewed: Boolean) {
dataStore.updateData { preferences ->
if (isViewed) {
- preferences.toBuilder().setFeatureUsedTimestampMillis(System.currentTimeMillis()).build()
+ preferences.toBuilder().setAppHandleHintUsedTimestampMillis(System.currentTimeMillis()).build()
} else {
- preferences.toBuilder().clearFeatureUsedTimestampMillis().build()
+ preferences.toBuilder().clearAppHandleHintUsedTimestampMillis().build()
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/proto/windowing_education.proto b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/proto/windowing_education.proto
index 4cddd01ee96b..0c4d562b8d55 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/proto/windowing_education.proto
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/education/data/proto/windowing_education.proto
@@ -22,9 +22,19 @@ option java_multiple_files = true;
// Desktop Windowing education data
message WindowingEducationProto {
// Timestamp in milliseconds of when the education was last viewed.
- optional int64 education_viewed_timestamp_millis = 1;
+ optional int64 education_viewed_timestamp_millis = 1 [deprecated=true];
// Timestamp in milliseconds of when the feature was last used.
- optional int64 feature_used_timestamp_millis = 2;
+ optional int64 feature_used_timestamp_millis = 2 [deprecated=true];
+
+ // Timestamp in milliseconds of when the app handle hint was last viewed.
+ optional int64 app_handle_hint_viewed_timestamp_millis = 5;
+ // Timestamp in milliseconds of when the app handle hint was last used.
+ optional int64 app_handle_hint_used_timestamp_millis = 6;
+ // Timestamp in milliseconds of when the enter desktop mode hint was last viewed.
+ optional int64 enter_desktop_mode_hint_viewed_timestamp_millis = 7;
+ // Timestamp in milliseconds of when the exit desktop mode hint was last viewed.
+ optional int64 exit_desktop_mode_hint_viewed_timestamp_millis = 8;
+
oneof education_data {
// Fields specific to app handle education
AppHandleEducation app_handle_education = 3;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index f7aed4401247..72c1ef06806a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -73,6 +73,7 @@ import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.common.pip.PipMenuController;
import com.android.wm.shell.common.pip.PipUtils;
+import com.android.wm.shell.common.split.SplitScreenUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.TransitionUtil;
import com.android.wm.shell.shared.pip.PipContentOverlay;
@@ -1346,6 +1347,13 @@ public class PipTransition extends PipTransitionController {
return true;
}
+ @Override
+ public boolean isPackageActiveInPip(@Nullable String packageName) {
+ final TaskInfo inPipTask = mPipOrganizer.getTaskInfo();
+ return packageName != null && inPipTask != null && mPipOrganizer.isInPip()
+ && packageName.equals(SplitScreenUtils.getPackageName(inPipTask.baseIntent));
+ }
+
private void updatePipForUnhandledTransition(@NonNull TransitionInfo.Change pipChange,
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index 79a9ce5212c6..a273822759f6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -312,9 +312,8 @@ public abstract class PipTransitionController implements Transitions.TransitionH
/** Whether a particular package is same as current pip package. */
public boolean isPackageActiveInPip(@Nullable String packageName) {
- return packageName != null
- && mPipBoundsState.getLastPipComponentName() != null
- && packageName.equals(mPipBoundsState.getLastPipComponentName().getPackageName());
+ // No-op, to be handled differently in PIP1 and PIP2
+ return false;
}
/** Add PiP-related changes to `outWCT` for the given request. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 2bcbe3013397..8ee087b33609 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -371,7 +371,9 @@ public class PipTransition extends PipTransitionController implements
// Update the src-rect-hint in params in place, to set up initial animator transform.
Rect sourceRectHint = getAdjustedSourceRectHint(info, pipChange, pipActivityChange);
- pipChange.getTaskInfo().pictureInPictureParams.getSourceRectHint().set(sourceRectHint);
+ final PictureInPictureParams params = getPipParams(pipChange);
+ params.copyOnlySet(
+ new PictureInPictureParams.Builder().setSourceRectHint(sourceRectHint).build());
// Config-at-end transitions need to have their activities transformed before starting
// the animation; this makes the buffer seem like it's been updated to final size.
@@ -416,9 +418,7 @@ public class PipTransition extends PipTransitionController implements
final SurfaceControl pipLeash = getLeash(pipChange);
final Rect startBounds = pipChange.getStartAbsBounds();
final Rect endBounds = pipChange.getEndAbsBounds();
- final PictureInPictureParams params = pipChange.getTaskInfo().pictureInPictureParams != null
- ? pipChange.getTaskInfo().pictureInPictureParams
- : new PictureInPictureParams.Builder().build();
+ final PictureInPictureParams params = getPipParams(pipChange);
final Rect adjustedSourceRectHint = getAdjustedSourceRectHint(info, pipChange,
pipActivityChange);
@@ -598,10 +598,10 @@ public class PipTransition extends PipTransitionController implements
PictureInPictureParams params = null;
if (pipChange.getTaskInfo() != null) {
// single activity
- params = pipChange.getTaskInfo().pictureInPictureParams;
+ params = getPipParams(pipChange);
} else if (parentBeforePip != null && parentBeforePip.getTaskInfo() != null) {
// multi activity
- params = parentBeforePip.getTaskInfo().pictureInPictureParams;
+ params = getPipParams(parentBeforePip);
}
final Rect sourceRectHint = PipBoundsAlgorithm.getValidSourceHintRect(params, endBounds,
startBounds);
@@ -842,19 +842,25 @@ public class PipTransition extends PipTransitionController implements
initActivityPos.y);
}
}
+ void cacheAndStartTransitionAnimator(@NonNull ValueAnimator animator) {
+ mTransitionAnimator = animator;
+ mTransitionAnimator.start();
+ }
+
+ @NonNull
+ private static PictureInPictureParams getPipParams(@NonNull TransitionInfo.Change pipChange) {
+ return pipChange.getTaskInfo().pictureInPictureParams != null
+ ? pipChange.getTaskInfo().pictureInPictureParams
+ : new PictureInPictureParams.Builder().build();
+ }
@NonNull
- private SurfaceControl getLeash(TransitionInfo.Change change) {
+ private static SurfaceControl getLeash(TransitionInfo.Change change) {
SurfaceControl leash = change.getLeash();
Preconditions.checkNotNull(leash, "Leash is null for change=" + change);
return leash;
}
- void cacheAndStartTransitionAnimator(@NonNull ValueAnimator animator) {
- mTransitionAnimator = animator;
- mTransitionAnimator.start();
- }
-
//
// Miscellaneous callbacks and listeners
//
@@ -904,9 +910,21 @@ public class PipTransition extends PipTransitionController implements
"Unexpected bundle for " + mPipTransitionState);
break;
case PipTransitionState.EXITED_PIP:
+ // Save the PiP bounds in case, we re-enter the PiP with the same component.
+ float snapFraction = mPipBoundsAlgorithm.getSnapFraction(
+ mPipBoundsState.getBounds());
+ mPipBoundsState.saveReentryState(snapFraction);
+
mPipTransitionState.setPipTaskToken(null);
mPipTransitionState.setPinnedTaskLeash(null);
break;
}
}
+
+ @Override
+ public boolean isPackageActiveInPip(@Nullable String packageName) {
+ return packageName != null
+ && mPipBoundsState.getLastPipComponentName() != null
+ && packageName.equals(mPipBoundsState.getLastPipComponentName().getPackageName());
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index d917f937b16c..363c95fcf010 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -19,8 +19,10 @@ package com.android.wm.shell.recents;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.PackageManager.FEATURE_PC;
+import static android.view.Display.INVALID_DISPLAY;
import static com.android.wm.shell.Flags.enableShellTopTaskTracking;
+import static com.android.wm.shell.desktopmode.DesktopWallpaperActivity.isWallpaperTask;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_OBSERVER;
import static com.android.wm.shell.shared.ShellSharedConstants.KEY_EXTRA_SHELL_RECENT_TASKS;
@@ -53,6 +55,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
+import com.android.launcher3.Flags;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.RemoteCallable;
import com.android.wm.shell.common.ShellExecutor;
@@ -282,6 +285,17 @@ public class RecentTasksController implements TaskStackListenerCallback,
notifyRecentTasksChanged();
}
+ /**
+ * This method only gets notified when a task is removed from recents as a result of another
+ * task being added to recent tasks.
+ */
+ @Override
+ public void onRecentTaskRemovedForAddTask(int taskId) {
+ mDesktopRepository.ifPresent(
+ repo -> repo.removeFreeformTask(INVALID_DISPLAY, taskId)
+ );
+ }
+
public void onTaskAdded(RunningTaskInfo taskInfo) {
notifyRunningTaskAppeared(taskInfo);
}
@@ -530,6 +544,10 @@ public class RecentTasksController implements TaskStackListenerCallback,
groupedTasks.add(GroupedTaskInfo.forSplitTasks(taskInfo, pairedTaskInfo,
mTaskSplitBoundsMap.get(pairedTaskId)));
} else {
+ if (Flags.enableRefactorTaskThumbnail() && isWallpaperTask(taskInfo)) {
+ // Don't add the wallpaper task as an entry in grouped tasks
+ continue;
+ }
// TODO(346588978): Consolidate multiple visible fullscreen tasks into the same
// grouped task
groupedTasks.add(GroupedTaskInfo.forFullscreenTasks(taskInfo));
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 43ed23b3b52a..f48226930871 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
@@ -108,6 +108,8 @@ import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIController;
import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler;
import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger;
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum;
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator;
import com.android.wm.shell.desktopmode.DesktopRepository;
import com.android.wm.shell.desktopmode.DesktopTasksController;
@@ -228,6 +230,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
private final TaskPositionerFactory mTaskPositionerFactory;
private final FocusTransitionObserver mFocusTransitionObserver;
private final DesktopModeEventLogger mDesktopModeEventLogger;
+ private final DesktopModeUiEventLogger mDesktopModeUiEventLogger;
public DesktopModeWindowDecorViewModel(
Context context,
@@ -257,7 +260,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
WindowDecorCaptionHandleRepository windowDecorCaptionHandleRepository,
Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
FocusTransitionObserver focusTransitionObserver,
- DesktopModeEventLogger desktopModeEventLogger) {
+ DesktopModeEventLogger desktopModeEventLogger,
+ DesktopModeUiEventLogger desktopModeUiEventLogger) {
this(
context,
shellExecutor,
@@ -292,7 +296,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
activityOrientationChangeHandler,
new TaskPositionerFactory(),
focusTransitionObserver,
- desktopModeEventLogger);
+ desktopModeEventLogger,
+ desktopModeUiEventLogger);
}
@VisibleForTesting
@@ -330,7 +335,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
Optional<DesktopActivityOrientationChangeHandler> activityOrientationChangeHandler,
TaskPositionerFactory taskPositionerFactory,
FocusTransitionObserver focusTransitionObserver,
- DesktopModeEventLogger desktopModeEventLogger) {
+ DesktopModeEventLogger desktopModeEventLogger,
+ DesktopModeUiEventLogger desktopModeUiEventLogger) {
mContext = context;
mMainExecutor = shellExecutor;
mMainHandler = mainHandler;
@@ -393,6 +399,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
mTaskPositionerFactory = taskPositionerFactory;
mFocusTransitionObserver = focusTransitionObserver;
mDesktopModeEventLogger = desktopModeEventLogger;
+ mDesktopModeUiEventLogger = desktopModeUiEventLogger;
shellInit.addInitCallback(this::onInit, this);
}
@@ -577,7 +584,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
decoration.mTaskSurface, mContext, mMainHandler,
Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, source);
mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo, resizeTrigger,
- motionEvent);
+ DesktopModeEventLogger.getInputMethodFromMotionEvent(motionEvent));
decoration.closeHandleMenu();
decoration.closeMaximizeMenu();
}
@@ -637,6 +644,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
decoration.addCaptionInset(wct);
mDesktopTasksController.moveTaskToDesktop(taskId, wct, source);
decoration.closeHandleMenu();
+
+ if (source == DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON) {
+ mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_DESKTOP_MODE);
+ }
}
private void onToFullscreen(int taskId) {
@@ -652,6 +664,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
mDesktopTasksController.moveToFullscreen(taskId,
DesktopModeTransitionSource.APP_HANDLE_MENU_BUTTON);
}
+ mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_FULL_SCREEN);
}
private void onToSplitScreen(int taskId) {
@@ -664,6 +678,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
// we shouldn't receive input for it any longer.
decoration.disposeStatusBarInputLayer();
mDesktopTasksController.requestSplit(decoration.mTaskInfo, false /* leftOrTop */);
+ mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_SPLIT_SCREEN);
}
private void onNewWindow(int taskId) {
@@ -803,6 +819,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
} else if (id == R.id.back_button) {
mTaskOperations.injectBackKey(mDisplayId);
} else if (id == R.id.caption_handle || id == R.id.open_menu_button) {
+ if (id == R.id.caption_handle && !decoration.mTaskInfo.isFreeform()) {
+ // Clicking the App Handle.
+ mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
+ DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_TAP);
+ }
if (!decoration.isHandleMenuActive()) {
moveTaskToFront(decoration.mTaskInfo);
openHandleMenu(mTaskId);
@@ -1554,8 +1575,6 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
final DesktopModeTouchEventListener touchEventListener =
new DesktopModeTouchEventListener(taskInfo, taskPositioner);
- InputMethod inputMethod = DesktopModeEventLogger.Companion.getInputMethodFromMotionEvent(
- touchEventListener.mMotionEvent);
windowDecoration.setOnMaximizeOrRestoreClickListener(() -> {
onMaximizeOrRestore(taskInfo.taskId, "maximize_menu", ResizeTrigger.MAXIMIZE_MENU,
touchEventListener.mMotionEvent);
@@ -1566,11 +1585,15 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
return Unit.INSTANCE;
});
windowDecoration.setOnLeftSnapClickListener(() -> {
- onSnapResize(taskInfo.taskId, /* isLeft= */ true, inputMethod);
+ onSnapResize(taskInfo.taskId, /* isLeft= */ true,
+ DesktopModeEventLogger.getInputMethodFromMotionEvent(
+ touchEventListener.mMotionEvent));
return Unit.INSTANCE;
});
windowDecoration.setOnRightSnapClickListener(() -> {
- onSnapResize(taskInfo.taskId, /* isLeft= */ false, inputMethod);
+ onSnapResize(taskInfo.taskId, /* isLeft= */ false,
+ DesktopModeEventLogger.getInputMethodFromMotionEvent(
+ touchEventListener.mMotionEvent));
return Unit.INSTANCE;
});
windowDecoration.setOnToDesktopClickListener(desktopModeTransitionSource -> {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index b6fa059e891d..d57044a4d27c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -1417,7 +1417,6 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
mHandleMenu.show(
/* onToDesktopClickListener= */ () -> {
mOnToDesktopClickListener.accept(APP_HANDLE_MENU_BUTTON);
- mOnToDesktopClickListener.accept(APP_HANDLE_MENU_BUTTON);
return Unit.INSTANCE;
},
/* onToFullscreenClickListener= */ mOnToFullscreenClickListener,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index b3213996b868..a6d503d0d991 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -460,7 +460,7 @@ class DragResizeInputListener implements AutoCloseable {
|| ctrlType == CTRL_TYPE_RIGHT || ctrlType == CTRL_TYPE_LEFT)
? ResizeTrigger.EDGE : ResizeTrigger.CORNER;
mDesktopModeEventLogger.logTaskResizingStarted(mResizeTrigger,
- DesktopModeEventLogger.Companion.getInputMethodFromMotionEvent(e),
+ DesktopModeEventLogger.getInputMethodFromMotionEvent(e),
mTaskInfo, mDragStartTaskBounds.width(),
mDragStartTaskBounds.height(), /* displayController= */ null,
/* displayLayoutSize= */ mDisplayLayoutSizeSupplier.get());
@@ -514,7 +514,7 @@ class DragResizeInputListener implements AutoCloseable {
}
mDesktopModeEventLogger.logTaskResizingEnded(mResizeTrigger,
- DesktopModeEventLogger.Companion.getInputMethodFromMotionEvent(
+ DesktopModeEventLogger.getInputMethodFromMotionEvent(
mLastMotionEventOnDown), mTaskInfo, taskBounds.width(),
taskBounds.height(),
/* displayController= */ null,
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 6f72d34eb0ae..c8aff78cbb36 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
@@ -74,8 +74,7 @@ public final class DragResizeWindowGeometry {
mFineTaskCorners = new TaskCorners(mTaskSize, fineCornerSize, disabledEdge);
// Save touch areas for each edge.
- mTaskEdges = new TaskEdges(mTaskSize, mResizeHandleEdgeOutset, mResizeHandleEdgeInset,
- mDisabledEdge);
+ mTaskEdges = new TaskEdges(mTaskSize, mResizeHandleEdgeOutset, mDisabledEdge);
}
/**
@@ -459,7 +458,7 @@ public final class DragResizeWindowGeometry {
private final @NonNull DisabledEdge mDisabledEdge;
private TaskEdges(@NonNull Size taskSize, int resizeHandleThickness,
- int resizeHandleEdgeInset, DisabledEdge disabledEdge) {
+ DisabledEdge disabledEdge) {
// Save touch areas for each edge.
mDisabledEdge = disabledEdge;
// Save touch areas for each edge.
@@ -471,16 +470,16 @@ public final class DragResizeWindowGeometry {
mLeftEdgeBounds = new Rect(
-resizeHandleThickness,
0,
- resizeHandleEdgeInset,
+ resizeHandleThickness,
taskSize.getHeight());
mRightEdgeBounds = new Rect(
- taskSize.getWidth() - resizeHandleEdgeInset,
+ taskSize.getWidth() - resizeHandleThickness,
0,
taskSize.getWidth() + resizeHandleThickness,
taskSize.getHeight());
mBottomEdgeBounds = new Rect(
-resizeHandleThickness,
- taskSize.getHeight() - resizeHandleEdgeInset,
+ taskSize.getHeight() - resizeHandleThickness,
taskSize.getWidth() + resizeHandleThickness,
taskSize.getHeight() + resizeHandleThickness);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
index 6cdc517c9cb7..583282247f58 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManager.kt
@@ -18,10 +18,12 @@ package com.android.wm.shell.windowdecor.tiling
import android.content.Context
import android.content.res.Configuration
+import android.graphics.Path
import android.graphics.PixelFormat
import android.graphics.Rect
import android.graphics.Region
import android.os.Binder
+import android.util.Size
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.RoundedCorner
@@ -40,7 +42,6 @@ import android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER
import android.view.WindowlessWindowManager
import com.android.wm.shell.R
import com.android.wm.shell.common.SyncTransactionQueue
-import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import java.util.function.Supplier
/**
@@ -48,7 +49,7 @@ import java.util.function.Supplier
* when two tasks are tiled on left and right to resize them simultaneously.
*/
class DesktopTilingDividerWindowManager(
- private val config: Configuration,
+ config: Configuration,
private val windowName: String,
private val context: Context,
private val leash: SurfaceControl,
@@ -61,7 +62,11 @@ class DesktopTilingDividerWindowManager(
private lateinit var viewHost: SurfaceControlViewHost
private var tilingDividerView: TilingDividerView? = null
private var dividerShown = false
- private var handleRegionWidth: Int = -1
+ private var handleRegionSize: Size =
+ Size(
+ context.resources.getDimensionPixelSize(R.dimen.split_divider_handle_region_width),
+ context.resources.getDimensionPixelSize(R.dimen.split_divider_handle_region_height),
+ )
private var setTouchRegion = true
private val maxRoundedCornerRadius = getMaxRoundedCornerRadius()
@@ -74,9 +79,62 @@ class DesktopTilingDividerWindowManager(
rect.set(dividerBounds)
}
- /** Sets the touch region for the SurfaceControlViewHost. */
- fun setTouchRegion(region: Rect) {
- setTouchRegion(viewHost.windowToken.asBinder(), Region(region))
+ /**
+ * Sets the touch region for the SurfaceControlViewHost.
+ *
+ * The region includes the area around the handle (for accessibility), the divider itself and
+ * the rounded corners (to prevent click reaching windows behind).
+ */
+ fun setTouchRegion(handle: Rect, divider: Rect, cornerRadius: Float) {
+ val path = Path()
+ path.fillType = Path.FillType.WINDING
+ // The UI starts on the top-left corner, the region will be:
+ //
+ // cornerLeft cornerRight
+ // c1Top +--------+
+ // |corners |
+ // c1Bottom +--+ +--+
+ // | |
+ // handleLeft| | handleRight
+ // handleTop +----+ +----+
+ // | handle |
+ // handleBot +----+ +----+
+ // | |
+ // | |
+ // c2Top +--+ +--+
+ // |corners |
+ // c2Bottom +--------+
+ val cornerLeft = 0f
+ val centerX = cornerRadius + divider.width() / 2f
+ val centerY = divider.height()
+ val cornerRight = divider.width() + 2 * cornerRadius
+ val handleLeft = centerX - handle.width() / 2f
+ val handleRight = handleLeft + handle.width()
+ val dividerLeft = centerY - divider.width() / 2f
+ val dividerRight = dividerLeft + divider.width()
+
+ val c1Top = 0f
+ val c1Bottom = cornerRadius
+ val handleTop = centerY - handle.height() / 2f
+ val handleBottom = handleTop + handle.height()
+ val c2Top = divider.height() - cornerRadius
+ val c2Bottom = divider.height().toFloat()
+
+ // Top corners
+ path.addRect(cornerLeft, c1Top, cornerRight, c1Bottom, Path.Direction.CCW)
+ // Bottom corners
+ path.addRect(cornerLeft, c1Top, cornerRight, c2Bottom, Path.Direction.CCW)
+ // Handle
+ path.addRect(handleLeft, handleTop, handleRight, handleBottom, Path.Direction.CCW)
+ // Divider
+ path.addRect(dividerLeft, c2Top, dividerRight, c2Bottom, Path.Direction.CCW)
+
+ val clip = Rect(handleLeft.toInt(), c1Top.toInt(), handleRight.toInt(), c2Bottom.toInt())
+
+ val region = Region()
+ region.setPath(path, Region(clip))
+
+ setTouchRegion(viewHost.windowToken.asBinder(), region)
}
/**
@@ -96,7 +154,7 @@ class DesktopTilingDividerWindowManager(
surfaceControlViewHost.setView(dividerView, lp)
val tmpDividerBounds = Rect()
getDividerBounds(tmpDividerBounds)
- dividerView.setup(this, tmpDividerBounds)
+ dividerView.setup(this, tmpDividerBounds, handleRegionSize)
t.setRelativeLayer(leash, relativeLeash, 1)
.setPosition(
leash,
@@ -112,7 +170,7 @@ class DesktopTilingDividerWindowManager(
viewHost = surfaceControlViewHost
dividerView.addOnLayoutChangeListener(this)
tilingDividerView = dividerView
- handleRegionWidth = dividerView.handleRegionWidth
+ updateTouchRegion()
}
/** Hides the divider bar. */
@@ -176,8 +234,8 @@ class DesktopTilingDividerWindowManager(
private fun getWindowManagerParams(): WindowManager.LayoutParams {
val lp =
WindowManager.LayoutParams(
- dividerBounds.width() + 2 * maxRoundedCornerRadius,
- dividerBounds.height(),
+ /* w= */ dividerBounds.width() + 2 * maxRoundedCornerRadius,
+ /* h= */ dividerBounds.height(),
TYPE_DOCK_DIVIDER,
FLAG_NOT_FOCUSABLE or
FLAG_NOT_TOUCH_MODAL or
@@ -216,13 +274,16 @@ class DesktopTilingDividerWindowManager(
) {
if (!setTouchRegion) return
- val startX = (dividerBounds.width() - handleRegionWidth) / 2
- val startY = 0
- val tempRect = Rect(startX, startY, startX + handleRegionWidth, dividerBounds.height())
- setTouchRegion(tempRect)
+ updateTouchRegion()
setTouchRegion = false
}
+ private fun updateTouchRegion() {
+ val startX = -handleRegionSize.width / 2
+ val handle = Rect(startX, 0, startX + handleRegionSize.width, dividerBounds.height())
+ setTouchRegion(handle, dividerBounds, maxRoundedCornerRadius.toFloat())
+ }
+
private fun setSlippery(slippery: Boolean) {
val lp = tilingDividerView?.layoutParams as WindowManager.LayoutParams
val isSlippery = (lp.flags and FLAG_SLIPPERY) != 0
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index bc7576c91da2..3b5c6ca2e58a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -492,9 +492,8 @@ class DesktopTilingWindowDecoration(
// Only called if [taskInfo] relates to a focused task
private fun isTilingRefocused(taskInfo: RunningTaskInfo): Boolean {
- return !isTilingFocused &&
- (taskInfo.taskId == leftTaskResizingHelper?.taskInfo?.taskId ||
- taskInfo.taskId == rightTaskResizingHelper?.taskInfo?.taskId)
+ return taskInfo.taskId == leftTaskResizingHelper?.taskInfo?.taskId ||
+ taskInfo.taskId == rightTaskResizingHelper?.taskInfo?.taskId
}
private fun buildTiledTasksMoveToFront(leftOnTop: Boolean): WindowContainerTransaction {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
index 111e28e450bd..b8e3b0fdb8d8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/TilingDividerView.kt
@@ -21,8 +21,10 @@ import android.graphics.Paint
import android.graphics.Rect
import android.provider.DeviceConfig
import android.util.AttributeSet
+import android.util.Size
import android.view.MotionEvent
import android.view.PointerIcon
+import android.view.RoundedCorner
import android.view.View
import android.view.ViewConfiguration
import android.widget.FrameLayout
@@ -42,6 +44,7 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion
private lateinit var callback: DividerMoveCallback
private lateinit var handle: DividerHandleView
private lateinit var corners: DividerRoundedCorner
+ private var cornersRadius: Int = 0
private var touchElevation = 0
private var moving = false
@@ -49,8 +52,7 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion
var handleRegionWidth: Int = 0
private var handleRegionHeight = 0
private var lastAcceptedPos = 0
- @VisibleForTesting var handleStartY = 0
- @VisibleForTesting var handleEndY = 0
+ @VisibleForTesting var handleY: IntRange = 0..0
private var canResize = false
private var resized = false
/**
@@ -79,16 +81,19 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion
) : super(context, attrs, defStyleAttr, defStyleRes)
/** Sets up essential dependencies of the divider bar. */
- fun setup(dividerMoveCallback: DividerMoveCallback, dividerBounds: Rect) {
+ fun setup(
+ dividerMoveCallback: DividerMoveCallback,
+ dividerBounds: Rect,
+ handleRegionSize: Size,
+ ) {
callback = dividerMoveCallback
this.dividerBounds.set(dividerBounds)
handle.setIsLeftRightSplit(true)
corners.setIsLeftRightSplit(true)
- handleRegionHeight =
- resources.getDimensionPixelSize(R.dimen.split_divider_handle_region_width)
-
- handleRegionWidth =
- resources.getDimensionPixelSize(R.dimen.split_divider_handle_region_height)
+ handleRegionHeight = handleRegionSize.height
+ handleRegionWidth = handleRegionSize.width
+ cornersRadius =
+ context.display.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT)?.radius ?: 0
initHandleYCoordinates()
dragDetector =
DragDetector(
@@ -241,17 +246,17 @@ class TilingDividerView : FrameLayout, View.OnTouchListener, DragDetector.Motion
return true
}
- private fun isWithinHandleRegion(touchYPos: Int): Boolean {
- return touchYPos in handleStartY..handleEndY
- }
+ private fun isWithinHandleRegion(touchYPos: Int): Boolean = touchYPos in handleY
private fun initHandleYCoordinates() {
- handleStartY = (dividerBounds.height() - handleRegionHeight) / 2
- handleEndY = handleStartY + handleRegionHeight
+ val handleStartY = (dividerBounds.height() - handleRegionHeight) / 2
+ val handleEndY = handleStartY + handleRegionHeight
+ handleY = handleStartY..handleEndY
}
companion object {
const val TOUCH_ANIMATION_DURATION: Long = 150
const val TOUCH_RELEASE_ANIMATION_DURATION: Long = 200
+ private val TAG = TilingDividerView::class.java.simpleName
}
}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
index 0cc8b0c7ba8d..d9c36cc70790 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/DesktopModeFlickerScenarios.kt
@@ -25,6 +25,7 @@ import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAlways
import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAtStart
import android.tools.flicker.assertors.assertions.AppWindowAlignsWithOnlyOneDisplayCornerAtEnd
import android.tools.flicker.assertors.assertions.AppWindowBecomesInvisible
+import android.tools.flicker.assertors.assertions.AppWindowBecomesPinned
import android.tools.flicker.assertors.assertions.AppWindowBecomesTopWindow
import android.tools.flicker.assertors.assertions.AppWindowBecomesVisible
import android.tools.flicker.assertors.assertions.AppWindowCoversLeftHalfScreenAtEnd
@@ -465,5 +466,25 @@ class DesktopModeFlickerScenarios {
AppWindowIsVisibleAlways(SIMPLE_APP)
).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
)
+
+ val MINIMIZE_AUTO_PIP_APP =
+ FlickerConfigEntry(
+ scenarioId = ScenarioId("MINIMIZE_AUTO_PIP_APP"),
+ extractor =
+ ShellTransitionScenarioExtractor(
+ transitionMatcher =
+ object : ITransitionMatcher {
+ override fun findAll(
+ transitions: Collection<Transition>
+ ): Collection<Transition> =
+ transitions.filter { it.type == TransitionType.PIP }
+ }
+ ),
+ assertions =
+ AssertionTemplates.COMMON_ASSERTIONS +
+ listOf(
+ AppWindowBecomesPinned(DESKTOP_MODE_APP),
+ ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING })
+ )
}
}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/MinimizeAutoPipAppWindow.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/MinimizeAutoPipAppWindow.kt
new file mode 100644
index 000000000000..b10db689e5bd
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/flicker-service/src/com/android/wm/shell/flicker/MinimizeAutoPipAppWindow.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.flicker
+
+import android.tools.flicker.FlickerConfig
+import android.tools.flicker.annotation.ExpectedScenarios
+import android.tools.flicker.annotation.FlickerConfigProvider
+import android.tools.flicker.config.FlickerConfig
+import android.tools.flicker.config.FlickerServiceConfig
+import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.wm.shell.flicker.DesktopModeFlickerScenarios.Companion.MINIMIZE_AUTO_PIP_APP
+import com.android.wm.shell.scenarios.MinimizeAutoPipAppWindow
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class MinimizeAutoPipAppWindow : MinimizeAutoPipAppWindow() {
+ @ExpectedScenarios(["MINIMIZE_AUTO_PIP_APP"])
+ @Test
+ override fun minimizePipAppWindow() = super.minimizePipAppWindow()
+
+ companion object {
+ @JvmStatic
+ @FlickerConfigProvider
+ fun flickerConfigProvider(): FlickerConfig =
+ FlickerConfig().use(FlickerServiceConfig.DEFAULT).use(MINIMIZE_AUTO_PIP_APP)
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindowAndPip.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindowAndPip.kt
index c43a57594fb3..bb812ad51135 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindowAndPip.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/DragAppWindowMultiWindowAndPip.kt
@@ -45,9 +45,9 @@ open class DragAppWindowMultiWindowAndPip : DragAppWindowScenarioTestBase()
@Before
fun setup() {
Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+ testApp.enterDesktopMode(wmHelper, device)
// Set string extra to ensure the app is on PiP mode at launch
pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = mapOf("enter_pip" to "true"))
- testApp.enterDesktopMode(wmHelper, device)
mailApp.launchViaIntent(wmHelper)
newTasksApp.launchViaIntent(wmHelper)
imeApp.launchViaIntent(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindowAndPip.kt b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindowAndPip.kt
index 0226eb35de14..41452c3bdd9f 100644
--- a/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindowAndPip.kt
+++ b/libs/WindowManager/Shell/tests/e2e/desktopmode/scenarios/src/com/android/wm/shell/scenarios/ResizeAppCornerMultiWindowAndPip.kt
@@ -63,9 +63,9 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0,
Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
tapl.setEnableRotation(true)
tapl.setExpectedRotation(rotation.value)
+ testApp.enterDesktopMode(wmHelper, device)
// Set string extra to ensure the app is on PiP mode at launch
pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = mapOf("enter_pip" to "true"))
- testApp.enterDesktopMode(wmHelper, device)
mailApp.launchViaIntent(wmHelper)
newTasksApp.launchViaIntent(wmHelper)
imeApp.launchViaIntent(wmHelper)
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
index 176020ffc3b9..6d12b00a61e6 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/Android.bp
@@ -49,6 +49,7 @@ java_library {
"wm-flicker-common-assertions",
"launcher-helper-lib",
"launcher-aosp-tapl",
+ "com_android_wm_shell_flags_lib",
],
}
diff --git a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
index 6d396ea6e9d4..9c71510df8a0 100644
--- a/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/e2e/splitscreen/flicker-legacy/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
@@ -17,12 +17,16 @@
package com.android.wm.shell.flicker.splitscreen
import android.platform.test.annotations.Presubmit
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
import android.tools.flicker.legacy.LegacyFlickerTestFactory
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
+import com.android.wm.shell.Flags
import com.android.wm.shell.flicker.splitscreen.benchmark.DismissSplitScreenByGoHomeBenchmark
import com.android.wm.shell.flicker.utils.ICommonAssertions
import com.android.wm.shell.flicker.utils.appWindowBecomesInvisible
@@ -30,6 +34,7 @@ import com.android.wm.shell.flicker.utils.layerBecomesInvisible
import com.android.wm.shell.flicker.utils.splitAppLayerBoundsBecomesInvisible
import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesInvisible
import org.junit.FixMethodOrder
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
@@ -44,8 +49,13 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RequiresFlagsDisabled(Flags.FLAG_ENABLE_PIP2)
class DismissSplitScreenByGoHome(override val flicker: LegacyFlickerTest) :
DismissSplitScreenByGoHomeBenchmark(flicker), ICommonAssertions {
+ @JvmField
+ @Rule
+ val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
override val transition: FlickerBuilder.() -> Unit
get() = {
defaultSetup(this)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
index 9c31b46a80e5..310c2d725c09 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java
@@ -26,6 +26,7 @@ import static org.mockito.Mockito.mock;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.WindowConfiguration;
+import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Rect;
@@ -42,7 +43,9 @@ public final class TestRunningTaskInfoBuilder {
private int mParentTaskId = INVALID_TASK_ID;
private int mUid = INVALID_TASK_ID;
private int mTaskId = INVALID_TASK_ID;
+ private int mUserId = -1;
private Intent mBaseIntent = new Intent();
+ private ComponentName mBaseActivity = null;
private @WindowConfiguration.ActivityType int mActivityType = ACTIVITY_TYPE_STANDARD;
private @WindowConfiguration.WindowingMode int mWindowingMode = WINDOWING_MODE_UNDEFINED;
private @WindowConfiguration.ActivityType int mTopActivityType = ACTIVITY_TYPE_STANDARD;
@@ -88,6 +91,12 @@ public final class TestRunningTaskInfoBuilder {
return this;
}
+ /** Sets the task info's user id. */
+ public TestRunningTaskInfoBuilder setUserId(int userId) {
+ mUserId = userId;
+ return this;
+ }
+
/**
* Set {@link ActivityManager.RunningTaskInfo#baseIntent} for the task info, by default
* an empty intent is assigned
@@ -97,6 +106,14 @@ public final class TestRunningTaskInfoBuilder {
return this;
}
+ /**
+ * Set {@link ActivityManager.RunningTaskInfo#baseActivity} for the task info.
+ */
+ public TestRunningTaskInfoBuilder setBaseActivity(@NonNull ComponentName activity) {
+ mBaseActivity = activity;
+ return this;
+ }
+
public TestRunningTaskInfoBuilder setActivityType(
@WindowConfiguration.ActivityType int activityType) {
mActivityType = activityType;
@@ -172,6 +189,8 @@ public final class TestRunningTaskInfoBuilder {
info.isTopActivityTransparent = mIsTopActivityTransparent;
info.numActivities = mNumActivities;
info.lastActiveTime = mLastActiveTime;
+ info.userId = mUserId;
+ info.baseActivity = mBaseActivity;
return info;
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
index 803e5d4442a9..1d390007d470 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
@@ -21,7 +21,7 @@ import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
index aabd973fce90..2ea0379e3bf7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopActivityOrientationChangeHandlerTest.kt
@@ -39,8 +39,8 @@ import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.common.TaskStackListenerImpl
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
import com.android.wm.shell.desktopmode.persistence.Desktop
import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
index 4666276c2fae..b57c55c4c45a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopImmersiveControllerTest.kt
@@ -43,7 +43,7 @@ import com.android.wm.shell.TestShellExecutor
import com.android.wm.shell.common.DisplayController
import com.android.wm.shell.common.DisplayLayout
import com.android.wm.shell.desktopmode.DesktopImmersiveController.ExitReason.USER_INTERACTION
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.util.StubTransaction
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
index 7adc339c010d..887bdc259f54 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeKeyGestureHandlerTest.kt
@@ -38,7 +38,7 @@ import com.android.wm.shell.MockToken
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
import com.android.wm.shell.transition.FocusTransitionObserver
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -266,7 +266,7 @@ class DesktopModeKeyGestureHandlerTest : ShellTestCase() {
verify(desktopTasksController).toggleDesktopTaskSize(
task,
ResizeTrigger.MAXIMIZE_MENU,
- null
+ DesktopModeEventLogger.Companion.InputMethod.KEYBOARD
)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt
index a8b2811e46be..94698e2fc0fb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeUiEventLoggerTest.kt
@@ -17,16 +17,22 @@
package com.android.wm.shell.desktopmode
+import android.content.ComponentName
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger.DesktopUiEventEnum.DESKTOP_WINDOW_EDGE_DRAG_RESIZE
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
/**
* Test class for [DesktopModeUiEventLogger]
@@ -39,11 +45,12 @@ class DesktopModeUiEventLoggerTest : ShellTestCase() {
private lateinit var uiEventLoggerFake: UiEventLoggerFake
private lateinit var logger: DesktopModeUiEventLogger
+ private val mockPackageManager: PackageManager = mock<PackageManager>()
@Before
fun setUp() {
uiEventLoggerFake = UiEventLoggerFake()
- logger = DesktopModeUiEventLogger(uiEventLoggerFake)
+ logger = DesktopModeUiEventLogger(uiEventLoggerFake, mockPackageManager)
}
@Test
@@ -100,10 +107,28 @@ class DesktopModeUiEventLoggerTest : ShellTestCase() {
assertThat(uiEventLoggerFake[0].packageName).isEqualTo(PACKAGE_NAME)
}
+ @Test
+ fun logWithTaskInfo_eventLogged() {
+ val event =
+ DESKTOP_WINDOW_EDGE_DRAG_RESIZE
+ val taskInfo = TestRunningTaskInfoBuilder()
+ .setUserId(USER_ID)
+ .setBaseActivity(ComponentName(PACKAGE_NAME, "test"))
+ .build()
+ whenever(mockPackageManager.getApplicationInfoAsUser(PACKAGE_NAME, /* flags= */ 0, USER_ID))
+ .thenReturn(ApplicationInfo().apply { uid = UID })
+ logger.log(taskInfo, event)
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(event.id)
+ assertThat(uiEventLoggerFake[0].instanceId).isNull()
+ assertThat(uiEventLoggerFake[0].uid).isEqualTo(UID)
+ assertThat(uiEventLoggerFake[0].packageName).isEqualTo(PACKAGE_NAME)
+ }
companion object {
private val INSTANCE_ID = InstanceId.fakeInstanceId(0)
private const val UID = 10
+ private const val USER_ID = 2
private const val PACKAGE_NAME = "com.foo"
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
index e977966a45fe..8e323acc4e66 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTaskChangeListenerTest.kt
@@ -23,8 +23,8 @@ import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGATION
import com.android.wm.shell.ShellTestCase
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
import org.junit.Before
import org.junit.Rule
import org.junit.Test
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 a8cfef7c1262..fc31d08b4571 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
@@ -99,10 +99,10 @@ import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeT
import com.android.wm.shell.desktopmode.DesktopTasksController.DesktopModeEntryExitTransitionListener
import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
import com.android.wm.shell.desktopmode.DesktopTasksController.TaskbarDesktopTaskListener
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createSplitScreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createHomeTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createSplitScreenTask
import com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION
import com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler.FULLSCREEN_ANIMATION_DURATION
import com.android.wm.shell.desktopmode.minimize.DesktopWindowLimitRemoteHandler
@@ -220,6 +220,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
@Mock private lateinit var freeformTaskTransitionStarter: FreeformTaskTransitionStarter
@Mock private lateinit var mockHandler: Handler
@Mock private lateinit var desktopModeEventLogger: DesktopModeEventLogger
+ @Mock private lateinit var desktopModeUiEventLogger: DesktopModeUiEventLogger
@Mock lateinit var persistentRepository: DesktopPersistentRepository
@Mock lateinit var motionEvent: MotionEvent
@Mock lateinit var repositoryInitializer: DesktopRepositoryInitializer
@@ -346,6 +347,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
mockInteractionJankMonitor,
mockHandler,
desktopModeEventLogger,
+ desktopModeUiEventLogger,
desktopTilingDecorViewModel,
)
}
@@ -375,12 +377,12 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask()
val argumentCaptor = ArgumentCaptor.forClass(Boolean::class.java)
- controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- InputMethod.UNKNOWN_INPUT_METHOD,
+ InputMethod.TOUCH,
task1,
STABLE_BOUNDS.width(),
STABLE_BOUNDS.height(),
@@ -402,12 +404,12 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task1 = setUpFreeformTask(bounds = stableBounds, active = true)
val argumentCaptor = ArgumentCaptor.forClass(Boolean::class.java)
- controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task1, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(argumentCaptor.capture())
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- InputMethod.UNKNOWN_INPUT_METHOD,
+ InputMethod.TOUCH,
task1,
0,
0,
@@ -3357,14 +3359,14 @@ class DesktopTasksControllerTest : ShellTestCase() {
val bounds = Rect(0, 0, 100, 100)
val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
// Assert bounds set to stable bounds
val wct = getLatestToggleResizeDesktopTaskWct()
assertThat(findBoundsChange(wct, task)).isEqualTo(STABLE_BOUNDS)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- InputMethod.UNKNOWN_INPUT_METHOD,
+ InputMethod.TOUCH,
task,
STABLE_BOUNDS.width(),
STABLE_BOUNDS.height(),
@@ -3582,14 +3584,14 @@ class DesktopTasksControllerTest : ShellTestCase() {
// Bounds should be 1000 x 500, vertically centered in the 1000 x 1000 stable bounds
val expectedBounds = Rect(STABLE_BOUNDS.left, 250, STABLE_BOUNDS.right, 750)
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
// Assert bounds set to stable bounds
val wct = getLatestToggleResizeDesktopTaskWct()
assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- InputMethod.UNKNOWN_INPUT_METHOD,
+ InputMethod.TOUCH,
task,
expectedBounds.width(),
expectedBounds.height(),
@@ -3602,7 +3604,7 @@ class DesktopTasksControllerTest : ShellTestCase() {
val bounds = Rect(0, 0, 100, 100)
val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isEqualTo(bounds)
verify(desktopModeEventLogger, never()).logTaskResizingEnded(
any(), any(), any(), any(),
@@ -3616,18 +3618,18 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
// Maximize
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
// Restore
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
// Assert bounds set to last bounds before maximize
val wct = getLatestToggleResizeDesktopTaskWct()
assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- InputMethod.UNKNOWN_INPUT_METHOD,
+ InputMethod.TOUCH,
task,
boundsBeforeMaximize.width(),
boundsBeforeMaximize.height(),
@@ -3643,19 +3645,19 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
// Maximize
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS.left,
boundsBeforeMaximize.top, STABLE_BOUNDS.right, boundsBeforeMaximize.bottom)
// Restore
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
// Assert bounds set to last bounds before maximize
val wct = getLatestToggleResizeDesktopTaskWct()
assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- InputMethod.UNKNOWN_INPUT_METHOD,
+ InputMethod.TOUCH,
task,
boundsBeforeMaximize.width(),
boundsBeforeMaximize.height(),
@@ -3671,19 +3673,19 @@ class DesktopTasksControllerTest : ShellTestCase() {
}
// Maximize
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
task.configuration.windowConfiguration.bounds.set(boundsBeforeMaximize.left,
STABLE_BOUNDS.top, boundsBeforeMaximize.right, STABLE_BOUNDS.bottom)
// Restore
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
// Assert bounds set to last bounds before maximize
val wct = getLatestToggleResizeDesktopTaskWct()
assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- InputMethod.UNKNOWN_INPUT_METHOD,
+ InputMethod.TOUCH,
task,
boundsBeforeMaximize.width(),
boundsBeforeMaximize.height(),
@@ -3697,17 +3699,17 @@ class DesktopTasksControllerTest : ShellTestCase() {
val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
// Maximize
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
// Restore
- controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, motionEvent)
+ controller.toggleDesktopTaskSize(task, ResizeTrigger.MAXIMIZE_BUTTON, InputMethod.TOUCH)
// Assert last bounds before maximize removed after use
assertThat(taskRepository.removeBoundsBeforeMaximize(task.taskId)).isNull()
verify(desktopModeEventLogger, times(1)).logTaskResizingEnded(
ResizeTrigger.MAXIMIZE_BUTTON,
- InputMethod.UNKNOWN_INPUT_METHOD,
+ InputMethod.TOUCH,
task,
boundsBeforeMaximize.width(),
boundsBeforeMaximize.height(),
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
index 456b50da095b..797b12505ef2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
@@ -42,7 +42,7 @@ import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_BACK_NAVIGAT
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.ShellExecutor
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
import com.android.wm.shell.desktopmode.persistence.DesktopPersistentRepository
import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
index 2134f3bb35cc..866d1b3880b0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
@@ -27,78 +27,56 @@ import android.view.Display.DEFAULT_DISPLAY
import com.android.wm.shell.MockToken
import com.android.wm.shell.TestRunningTaskInfoBuilder
-class DesktopTestHelpers {
- companion object {
- /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */
- @JvmStatic
- @JvmOverloads
- fun createFreeformTask(
- displayId: Int = DEFAULT_DISPLAY,
- bounds: Rect? = null
- ): RunningTaskInfo {
- return TestRunningTaskInfoBuilder()
- .setDisplayId(displayId)
- .setToken(MockToken().token())
- .setActivityType(ACTIVITY_TYPE_STANDARD)
- .setWindowingMode(WINDOWING_MODE_FREEFORM)
- .setLastActiveTime(100)
- .apply { bounds?.let { setBounds(it) }}
- .build()
- }
+object DesktopTestHelpers {
+ /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */
+ fun createFreeformTask(
+ displayId: Int = DEFAULT_DISPLAY,
+ bounds: Rect? = null,
+ ): RunningTaskInfo =
+ TestRunningTaskInfoBuilder()
+ .setDisplayId(displayId)
+ .setToken(MockToken().token())
+ .setActivityType(ACTIVITY_TYPE_STANDARD)
+ .setWindowingMode(WINDOWING_MODE_FREEFORM)
+ .setLastActiveTime(100)
+ .apply { bounds?.let { setBounds(it) } }
+ .build()
- /** Create a task builder that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
- @JvmStatic
- @JvmOverloads
- fun createFullscreenTaskBuilder(displayId: Int = DEFAULT_DISPLAY): TestRunningTaskInfoBuilder {
- return TestRunningTaskInfoBuilder()
- .setDisplayId(displayId)
- .setToken(MockToken().token())
- .setActivityType(ACTIVITY_TYPE_STANDARD)
- .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
- .setLastActiveTime(100)
- }
+ fun createFullscreenTaskBuilder(displayId: Int = DEFAULT_DISPLAY): TestRunningTaskInfoBuilder =
+ TestRunningTaskInfoBuilder()
+ .setDisplayId(displayId)
+ .setToken(MockToken().token())
+ .setActivityType(ACTIVITY_TYPE_STANDARD)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+ .setLastActiveTime(100)
- /** Create a task that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
- @JvmStatic
- @JvmOverloads
- fun createFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
- return createFullscreenTaskBuilder(displayId).build()
- }
+ /** Create a task that has windowing mode set to [WINDOWING_MODE_FULLSCREEN] */
+ fun createFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo =
+ createFullscreenTaskBuilder(displayId).build()
- /** Create a task that has windowing mode set to [WINDOWING_MODE_MULTI_WINDOW] */
- @JvmStatic
- @JvmOverloads
- fun createSplitScreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
- return TestRunningTaskInfoBuilder()
- .setDisplayId(displayId)
- .setToken(MockToken().token())
- .setActivityType(ACTIVITY_TYPE_STANDARD)
- .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW)
- .setLastActiveTime(100)
- .build()
- }
+ /** Create a task that has windowing mode set to [WINDOWING_MODE_MULTI_WINDOW] */
+ fun createSplitScreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo =
+ TestRunningTaskInfoBuilder()
+ .setDisplayId(displayId)
+ .setToken(MockToken().token())
+ .setActivityType(ACTIVITY_TYPE_STANDARD)
+ .setWindowingMode(WINDOWING_MODE_MULTI_WINDOW)
+ .setLastActiveTime(100)
+ .build()
- /** Create a new home task */
- @JvmStatic
- @JvmOverloads
- fun createHomeTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
- return TestRunningTaskInfoBuilder()
- .setDisplayId(displayId)
- .setToken(MockToken().token())
- .setActivityType(ACTIVITY_TYPE_HOME)
- .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
- .setLastActiveTime(100)
- .build()
- }
+ fun createHomeTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo =
+ TestRunningTaskInfoBuilder()
+ .setDisplayId(displayId)
+ .setToken(MockToken().token())
+ .setActivityType(ACTIVITY_TYPE_HOME)
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+ .setLastActiveTime(100)
+ .build()
- /** Create a new System Modal task, i.e. a task with a single transparent activity. */
- @JvmStatic
- @JvmOverloads
- fun createSystemModalTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
- return createFullscreenTaskBuilder(displayId)
- .setTopActivityTransparent(true)
- .setNumActivities(1)
- .build()
- }
- }
-} \ No newline at end of file
+ /** Create a new System Modal task, i.e. a task with a single transparent activity. */
+ fun createSystemModalTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo =
+ createFullscreenTaskBuilder(displayId)
+ .setTopActivityTransparent(true)
+ .setNumActivities(1)
+ .build()
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
index 79d90838cecc..226e974d2875 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
@@ -26,9 +26,9 @@ import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.desktopmode.DesktopRepository
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTaskBuilder
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createSystemModalTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFullscreenTaskBuilder
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createSystemModalTask
import com.android.wm.shell.sysui.ShellInit
import com.android.wm.shell.transition.TransitionInfoBuilder
import com.android.wm.shell.transition.Transitions
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt
index d94186c8284e..9c00c0cee8b1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationControllerTest.kt
@@ -175,13 +175,13 @@ class AppHandleEducationControllerTest : ShellTestCase() {
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION)
- fun init_educationViewedAlready_shouldNotCallShowEducationTooltip() =
+ fun init_appHandleHintViewedAlready_shouldNotCallShowEducationTooltip() =
testScope.runTest {
- // App handle is visible but education has been viewed before. Should not show education
- // tooltip.
- // Mark education viewed.
+ // App handle is visible but app handle hint has been viewed before,
+ // should not show education tooltip.
+ // Mark app handle hint viewed.
testDataStoreFlow.value =
- createWindowingEducationProto(educationViewedTimestampMillis = 123L)
+ createWindowingEducationProto(appHandleHintViewedTimestampMillis = 123L)
setShouldShowAppHandleEducation(true)
// Simulate app handle visible.
@@ -194,13 +194,14 @@ class AppHandleEducationControllerTest : ShellTestCase() {
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION)
- fun overridePrerequisite_educationViewedAlready_shouldCallShowEducationTooltip() =
+ fun overridePrerequisite_appHandleHintViewedAlready_shouldCallShowEducationTooltip() =
testScope.runTest {
- // App handle is visible but education has been viewed before. But as we are overriding
- // prerequisite conditions, we should show education tooltip.
- // Mark education viewed.
+ // App handle is visible but app handle hint has been viewed before.
+ // But as we are overriding prerequisite conditions, we should show app
+ // handle tooltip.
+ // Mark app handle hint viewed.
testDataStoreFlow.value =
- createWindowingEducationProto(educationViewedTimestampMillis = 123L)
+ createWindowingEducationProto(appHandleHintViewedTimestampMillis = 123L)
val systemPropertiesKey =
"persist.desktop_windowing_app_handle_education_override_conditions"
whenever(SystemProperties.getBoolean(eq(systemPropertiesKey), anyBoolean()))
@@ -217,7 +218,7 @@ class AppHandleEducationControllerTest : ShellTestCase() {
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION)
- fun init_appHandleExpanded_shouldMarkFeatureViewed() =
+ fun init_appHandleExpanded_shouldMarkAppHandleHintUsed() =
testScope.runTest {
setShouldShowAppHandleEducation(false)
@@ -226,12 +227,12 @@ class AppHandleEducationControllerTest : ShellTestCase() {
// Wait for some time before verifying
waitForBufferDelay()
- verify(mockDataStoreRepository, times(1)).updateFeatureUsedTimestampMillis(eq(true))
+ verify(mockDataStoreRepository, times(1)).updateAppHandleHintUsedTimestampMillis(eq(true))
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_HANDLE_EDUCATION)
- fun init_showFirstTooltip_shouldMarkEducationViewed() =
+ fun init_showFirstTooltip_shouldMarkAppHandleHintViewed() =
testScope.runTest {
// App handle is visible. Should show education tooltip.
setShouldShowAppHandleEducation(true)
@@ -241,7 +242,7 @@ class AppHandleEducationControllerTest : ShellTestCase() {
// Wait for first tooltip to showup.
waitForBufferDelay()
- verify(mockDataStoreRepository, times(1)).updateEducationViewedTimestampMillis(eq(true))
+ verify(mockDataStoreRepository, times(1)).updateAppHandleHintViewedTimestampMillis(eq(true))
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationDatastoreRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationDatastoreRepositoryTest.kt
index c2865441d7a6..963890d1caa4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationDatastoreRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationDatastoreRepositoryTest.kt
@@ -81,8 +81,8 @@ class AppHandleEducationDatastoreRepositoryTest {
runTest(StandardTestDispatcher()) {
val windowingEducationProto =
createWindowingEducationProto(
- educationViewedTimestampMillis = 123L,
- featureUsedTimestampMillis = 124L,
+ appHandleHintViewedTimestampMillis = 123L,
+ appHandleHintUsedTimestampMillis = 124L,
appUsageStats = mapOf(GMAIL_PACKAGE_NAME to 2),
appUsageStatsLastUpdateTimestampMillis = 125L)
testDatastore.updateData { windowingEducationProto }
@@ -110,20 +110,20 @@ class AppHandleEducationDatastoreRepositoryTest {
}
@Test
- fun updateEducationViewedTimestampMillis_updatesDatastoreProto() =
+ fun updateAppHandleHintViewedTimestampMillis_updatesDatastoreProto() =
runTest(StandardTestDispatcher()) {
- datastoreRepository.updateEducationViewedTimestampMillis(true)
+ datastoreRepository.updateAppHandleHintViewedTimestampMillis(true)
- val result = testDatastore.data.first().hasEducationViewedTimestampMillis()
+ val result = testDatastore.data.first().hasAppHandleHintViewedTimestampMillis()
assertThat(result).isEqualTo(true)
}
@Test
- fun updateFeatureUsedTimestampMillis_updatesDatastoreProto() =
+ fun updateAppHandleHintUsedTimestampMillis_updatesDatastoreProto() =
runTest(StandardTestDispatcher()) {
- datastoreRepository.updateFeatureUsedTimestampMillis(true)
+ datastoreRepository.updateAppHandleHintUsedTimestampMillis(true)
- val result = testDatastore.data.first().hasFeatureUsedTimestampMillis()
+ val result = testDatastore.data.first().hasAppHandleHintUsedTimestampMillis()
assertThat(result).isEqualTo(true)
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilterTest.kt
index a3e74e8aed5d..e5edd69155b5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilterTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/education/AppHandleEducationFilterTest.kt
@@ -134,12 +134,12 @@ class AppHandleEducationFilterTest : ShellTestCase() {
}
@Test
- fun shouldShowAppHandleEducation_educationViewedBefore_returnsFalse() = runTest {
- // Education has been viewed before, hence #shouldShowAppHandleEducation should return false
+ fun shouldShowAppHandleEducation_appHandleHintViewedBefore_returnsFalse() = runTest {
+ // App handle hint has been viewed before, hence #shouldShowAppHandleEducation should return false
val windowingEducationProto =
createWindowingEducationProto(
appUsageStats = mapOf(GMAIL_PACKAGE_NAME to 4),
- educationViewedTimestampMillis = 123L,
+ appHandleHintViewedTimestampMillis = 123L,
appUsageStatsLastUpdateTimestampMillis = Long.MAX_VALUE)
`when`(datastoreRepository.windowingEducationProto()).thenReturn(windowingEducationProto)
@@ -149,12 +149,12 @@ class AppHandleEducationFilterTest : ShellTestCase() {
}
@Test
- fun shouldShowAppHandleEducation_featureUsedBefore_returnsFalse() = runTest {
- // Feature has been used before, hence #shouldShowAppHandleEducation should return false
+ fun shouldShowAppHandleEducation_appHandleHintUsedBefore_returnsFalse() = runTest {
+ // App handle hint has been used before, hence #shouldShowAppHandleEducation should return false
val windowingEducationProto =
createWindowingEducationProto(
appUsageStats = mapOf(GMAIL_PACKAGE_NAME to 4),
- featureUsedTimestampMillis = 123L,
+ appHandleHintUsedTimestampMillis = 123L,
appUsageStatsLastUpdateTimestampMillis = Long.MAX_VALUE)
`when`(datastoreRepository.windowingEducationProto()).thenReturn(windowingEducationProto)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 12c397868f5a..68c8aab8849d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -22,6 +22,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.launcher3.Flags.FLAG_ENABLE_REFACTOR_TASK_THUMBNAIL;
import static com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
@@ -51,6 +52,7 @@ import android.app.ActivityTaskManager;
import android.app.KeyguardManager;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.graphics.Rect;
@@ -72,6 +74,7 @@ import com.android.wm.shell.TestShellExecutor;
import com.android.wm.shell.common.DisplayInsetsController;
import com.android.wm.shell.common.TaskStackListenerImpl;
import com.android.wm.shell.desktopmode.DesktopRepository;
+import com.android.wm.shell.desktopmode.DesktopWallpaperActivity;
import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.ShellSharedConstants;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
@@ -237,6 +240,19 @@ public class RecentTasksControllerTest extends ShellTestCase {
t3.taskId, -1);
}
+ @EnableFlags(FLAG_ENABLE_REFACTOR_TASK_THUMBNAIL)
+ @Test
+ public void testGetRecentTasks_removesDesktopWallpaperActivity() {
+ RecentTaskInfo t1 = makeTaskInfo(1);
+ RecentTaskInfo desktopWallpaperTaskInfo = makeDesktopWallpaperTaskInfo(2);
+ RecentTaskInfo t3 = makeTaskInfo(3);
+ setRawList(t1, desktopWallpaperTaskInfo, t3);
+
+ ArrayList<GroupedTaskInfo> recentTasks =
+ mRecentTasksController.getRecentTasks(MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
+ assertGroupedTasksListEquals(recentTasks, t1.taskId, -1, t3.taskId, -1);
+ }
+
@Test
public void testGetRecentTasks_withPairs() {
RecentTaskInfo t1 = makeTaskInfo(1);
@@ -691,11 +707,25 @@ public class RecentTasksControllerTest extends ShellTestCase {
private RecentTaskInfo makeTaskInfo(int taskId) {
RecentTaskInfo info = new RecentTaskInfo();
info.taskId = taskId;
+
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName("com." + taskId, "Activity" + taskId));
+ info.baseIntent = intent;
+
info.lastNonFullscreenBounds = new Rect();
return info;
}
/**
+ * Helper to create a desktop wallpaper activity with a given task id.
+ */
+ private RecentTaskInfo makeDesktopWallpaperTaskInfo(int taskId) {
+ RecentTaskInfo info = makeTaskInfo(taskId);
+ info.baseIntent.setComponent(DesktopWallpaperActivity.getWallpaperActivityComponent());
+ return info;
+ }
+
+ /**
* Helper to create a running task with a given task id.
*/
private ActivityManager.RunningTaskInfo makeRunningTaskInfo(int taskId) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/WindowingEducationTestUtils.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/WindowingEducationTestUtils.kt
index 99e82959fcd6..b9d91e7895db 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/WindowingEducationTestUtils.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/util/WindowingEducationTestUtils.kt
@@ -78,18 +78,18 @@ fun createTaskInfo(
* Any fields without corresponding parameters will retain their default values.
*/
fun createWindowingEducationProto(
- educationViewedTimestampMillis: Long? = null,
- featureUsedTimestampMillis: Long? = null,
+ appHandleHintViewedTimestampMillis: Long? = null,
+ appHandleHintUsedTimestampMillis: Long? = null,
appUsageStats: Map<String, Int>? = null,
appUsageStatsLastUpdateTimestampMillis: Long? = null
): WindowingEducationProto =
WindowingEducationProto.newBuilder()
.apply {
- if (educationViewedTimestampMillis != null) {
- setEducationViewedTimestampMillis(educationViewedTimestampMillis)
+ if (appHandleHintViewedTimestampMillis != null) {
+ setAppHandleHintViewedTimestampMillis(appHandleHintViewedTimestampMillis)
}
- if (featureUsedTimestampMillis != null) {
- setFeatureUsedTimestampMillis(featureUsedTimestampMillis)
+ if (appHandleHintUsedTimestampMillis != null) {
+ setAppHandleHintUsedTimestampMillis(appHandleHintUsedTimestampMillis)
}
setAppHandleEducation(
createAppHandleEducationProto(appUsageStats, appUsageStatsLastUpdateTimestampMillis))
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index 7bb8e891e33b..b873162e6fe3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -399,7 +399,7 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest
verify(mockDesktopTasksController).toggleDesktopTaskSize(
decor.mTaskInfo,
ResizeTrigger.MAXIMIZE_MENU,
- null
+ InputMethod.UNKNOWN_INPUT_METHOD
)
}
@@ -1033,7 +1033,11 @@ class DesktopModeWindowDecorViewModelTests : DesktopModeWindowDecorViewModelTest
onClickListenerCaptor.value.onClick(view)
verify(mockDesktopTasksController)
- .toggleDesktopTaskSize(decor.mTaskInfo, ResizeTrigger.MAXIMIZE_BUTTON, null)
+ .toggleDesktopTaskSize(
+ decor.mTaskInfo,
+ ResizeTrigger.MAXIMIZE_BUTTON,
+ InputMethod.UNKNOWN_INPUT_METHOD
+ )
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
index 91eaadaf1f18..1670f2a6815b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
@@ -55,6 +55,7 @@ import com.android.wm.shell.common.MultiInstanceHelper
import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopActivityOrientationChangeHandler
import com.android.wm.shell.desktopmode.DesktopModeEventLogger
+import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController
import com.android.wm.shell.desktopmode.DesktopTasksLimiter
@@ -199,7 +200,8 @@ open class DesktopModeWindowDecorViewModelTestsBase : ShellTestCase() {
Optional.of(mockActivityOrientationChangeHandler),
mockTaskPositionerFactory,
mockFocusTransitionObserver,
- desktopModeEventLogger
+ desktopModeEventLogger,
+ mock<DesktopModeUiEventLogger>()
)
desktopModeWindowDecorViewModel.setSplitScreenController(mockSplitScreenController)
whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
index e7d328e28297..479f1567ed31 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
@@ -63,6 +63,7 @@ public class DragResizeWindowGeometryTests extends ShellTestCase {
private static final int EDGE_RESIZE_HANDLE_INSET = 4;
private static final int FINE_CORNER_SIZE = EDGE_RESIZE_THICKNESS * 2 + 10;
private static final int LARGE_CORNER_SIZE = FINE_CORNER_SIZE + 10;
+ private static final int SMALL_OFFSET = 10;
private static final DragResizeWindowGeometry GEOMETRY = new DragResizeWindowGeometry(
TASK_CORNER_RADIUS, TASK_SIZE, EDGE_RESIZE_THICKNESS, EDGE_RESIZE_HANDLE_INSET,
FINE_CORNER_SIZE, LARGE_CORNER_SIZE, DragResizeWindowGeometry.DisabledEdge.NONE);
@@ -147,15 +148,19 @@ public class DragResizeWindowGeometryTests extends ShellTestCase {
assertThat(region.contains(point.x + EDGE_RESIZE_THICKNESS, point.y)).isTrue();
assertThat(region.contains(point.x - EDGE_RESIZE_THICKNESS, point.y)).isTrue();
// Vertically along the edge is not contained.
- assertThat(region.contains(point.x, point.y - EDGE_RESIZE_THICKNESS)).isFalse();
- assertThat(region.contains(point.x, point.y + EDGE_RESIZE_THICKNESS + 10)).isFalse();
+ assertThat(
+ region.contains(point.x, point.y - EDGE_RESIZE_THICKNESS - SMALL_OFFSET)).isFalse();
+ assertThat(
+ region.contains(point.x, point.y + EDGE_RESIZE_THICKNESS + SMALL_OFFSET)).isFalse();
}
private static void verifyVerticalEdge(@NonNull Region region, @NonNull Point point) {
assertThat(region.contains(point.x, point.y)).isTrue();
// Horizontally along the edge is not contained.
- assertThat(region.contains(point.x + EDGE_RESIZE_THICKNESS, point.y)).isFalse();
- assertThat(region.contains(point.x - EDGE_RESIZE_THICKNESS, point.y)).isFalse();
+ assertThat(
+ region.contains(point.x + EDGE_RESIZE_THICKNESS + SMALL_OFFSET, point.y)).isFalse();
+ assertThat(
+ region.contains(point.x - EDGE_RESIZE_THICKNESS - SMALL_OFFSET, point.y)).isFalse();
// Vertically along the edge is contained.
assertThat(region.contains(point.x, point.y - EDGE_RESIZE_THICKNESS)).isTrue();
assertThat(region.contains(point.x, point.y + EDGE_RESIZE_THICKNESS)).isTrue();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
index d8c1a11de452..d29002199f9d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
@@ -27,7 +27,7 @@ import com.android.wm.shell.common.SyncTransactionQueue
import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
import com.android.wm.shell.transition.Transitions
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
index 3143946fa828..121e0e915d08 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDividerWindowManagerTest.kt
@@ -122,6 +122,6 @@ class DesktopTilingDividerWindowManagerTest : ShellTestCase() {
companion object {
private val BOUNDS = Rect(1, 2, 3, 4)
- private val CORNER_RADIUS = 28
+ private const val CORNER_RADIUS = 28
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
index ad6fdf4d5c59..3b39f1e4a25a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
@@ -38,7 +38,7 @@ import com.android.wm.shell.desktopmode.DesktopModeEventLogger
import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger
import com.android.wm.shell.desktopmode.DesktopRepository
import com.android.wm.shell.desktopmode.DesktopTasksController
-import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
+import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler
import com.android.wm.shell.transition.Transitions
@@ -124,7 +124,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun taskTiled_toCorrectBounds_leftTile() {
- val task1 = createFreeformTask()
+ val task1 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -151,7 +151,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun taskTiled_toCorrectBounds_rightTile() {
// Setup
- val task1 = createFreeformTask()
+ val task1 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -177,7 +177,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun taskTiled_notAnimated_whenTilingPositionNotChange() {
- val task1 = createFreeformTask()
+ val task1 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -213,8 +213,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun taskNotTiled_notBroughtToFront_tilingNotInitialised() {
- val task1 = createFreeformTask()
- val task2 = createFreeformTask()
+ val task1 = createVisibleTask()
+ val task2 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -236,9 +236,9 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun taskNotTiled_notBroughtToFront_taskNotTiled() {
- val task1 = createFreeformTask()
- val task2 = createFreeformTask()
- val task3 = createFreeformTask()
+ val task1 = createVisibleTask()
+ val task2 = createVisibleTask()
+ val task3 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -265,9 +265,9 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
}
@Test
- fun taskTiled_broughtToFront_alreadyInFrontNoAction() {
- val task1 = createFreeformTask()
- val task2 = createFreeformTask()
+ fun taskTiled_broughtToFront_alreadyInFrontStillReorder() {
+ val task1 = createVisibleTask()
+ val task2 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -275,6 +275,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
}
whenever(context.resources).thenReturn(resources)
whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width)
+ whenever(desktopRepository.isVisibleTask(eq(task1.taskId))).thenReturn(true)
+ whenever(desktopRepository.isVisibleTask(eq(task2.taskId))).thenReturn(true)
tilingDecoration.onAppTiled(
task1,
@@ -290,15 +292,15 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
)
task1.isFocused = true
- assertThat(tilingDecoration.moveTiledPairToFront(task1)).isFalse()
- verify(transitions, never()).startTransition(any(), any(), any())
+ assertThat(tilingDecoration.moveTiledPairToFront(task1, isTaskFocused = true)).isTrue()
+ verify(transitions, times(1)).startTransition(eq(TRANSIT_TO_FRONT), any(), eq(null))
}
@Test
fun taskTiled_broughtToFront_bringToFront() {
- val task1 = createFreeformTask()
- val task2 = createFreeformTask()
- val task3 = createFreeformTask()
+ val task1 = createVisibleTask()
+ val task2 = createVisibleTask()
+ val task3 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
(i.arguments.first() as Rect).set(stableBounds)
@@ -329,9 +331,9 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun taskTiled_broughtToFront_taskInfoNotUpdated_bringToFront() {
- val task1 = createFreeformTask()
- val task2 = createFreeformTask()
- val task3 = createFreeformTask()
+ val task1 = createVisibleTask()
+ val task2 = createVisibleTask()
+ val task3 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
(i.arguments.first() as Rect).set(stableBounds)
@@ -361,8 +363,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun taskTiledTasks_NotResized_BeforeTouchEndArrival() {
// Setup
- val task1 = createFreeformTask()
- val task2 = createFreeformTask()
+ val task1 = createVisibleTask()
+ val task2 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -428,8 +430,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun tiledTasksResizedUsingDividerHandle_shouldLogResizingEvents() {
// Setup
- val task1 = createFreeformTask()
- val task2 = createFreeformTask()
+ val task1 = createVisibleTask()
+ val task2 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -487,7 +489,7 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun taskTiled_shouldBeRemoved_whenTileBroken() {
- val task1 = createFreeformTask()
+ val task1 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -516,8 +518,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun taskNotTiled_shouldNotBeRemoved_whenNotTiled() {
- val task1 = createFreeformTask()
- val task2 = createFreeformTask()
+ val task1 = createVisibleTask()
+ val task2 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -545,8 +547,8 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
@Test
fun tasksTiled_shouldBeRemoved_whenSessionDestroyed() {
- val task1 = createFreeformTask()
- val task2 = createFreeformTask()
+ val task1 = createVisibleTask()
+ val task2 = createVisibleTask()
val stableBounds = STABLE_BOUNDS_MOCK
whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
@@ -610,6 +612,11 @@ class DesktopTilingWindowDecorationTest : ShellTestCase() {
return Rect(stableBounds.left, stableBounds.top, rightBound, stableBounds.bottom)
}
+ private fun createVisibleTask() =
+ createFreeformTask().also {
+ whenever(desktopRepository.isVisibleTask(eq(it.taskId))).thenReturn(true)
+ }
+
companion object {
private val NON_STABLE_BOUNDS_MOCK = Rect(50, 55, 100, 100)
private val STABLE_BOUNDS_MOCK = Rect(0, 0, 100, 100)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt
index 734815cdd915..9a9d05a72442 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/TilingDividerViewTest.kt
@@ -19,9 +19,12 @@ package com.android.wm.shell.windowdecor.tiling
import android.graphics.Rect
import android.os.SystemClock
import android.testing.AndroidTestingRunner
+import android.util.Size
+import android.view.Display
import android.view.InputDevice
import android.view.LayoutInflater
import android.view.MotionEvent
+import android.view.RoundedCorner
import android.view.View
import androidx.test.annotation.UiThreadTest
import androidx.test.filters.SmallTest
@@ -46,16 +49,19 @@ class TilingDividerViewTest : ShellTestCase() {
private val dividerMoveCallbackMock = mock<DividerMoveCallback>()
private val viewMock = mock<View>()
+ private val display = mock<Display>()
+ private val roundedCorner = mock<RoundedCorner>()
@Before
@UiThreadTest
fun setUp() {
+ whenever(display.getRoundedCorner(any())).thenReturn(roundedCorner)
+ whenever(roundedCorner.radius).thenReturn(CORNER_RADIUS)
tilingDividerView =
LayoutInflater.from(mContext).inflate(R.layout.tiling_split_divider, /* root= */ null)
as TilingDividerView
- tilingDividerView.setup(dividerMoveCallbackMock, BOUNDS)
- tilingDividerView.handleStartY = 0
- tilingDividerView.handleEndY = 1500
+ tilingDividerView.setup(dividerMoveCallbackMock, DIVIDER_BOUNDS, HANDLE_SIZE)
+ tilingDividerView.handleY = 0..1500
}
@Test
@@ -130,6 +136,8 @@ class TilingDividerViewTest : ShellTestCase() {
}
companion object {
- private val BOUNDS = Rect(0, 0, 1500, 1500)
+ private val DIVIDER_BOUNDS = Rect(15, 0, 35, 1500)
+ private val HANDLE_SIZE = Size(800, 300)
+ private const val CORNER_RADIUS = 15
}
}
diff --git a/libs/hwui/jni/ColorFilter.cpp b/libs/hwui/jni/ColorFilter.cpp
index 20301d2c76ec..1c6d886f18b7 100644
--- a/libs/hwui/jni/ColorFilter.cpp
+++ b/libs/hwui/jni/ColorFilter.cpp
@@ -163,6 +163,20 @@ public:
filter->updateChild(env, name.c_str(), child);
}
}
+
+ static void RuntimeColorFilter_updateInputColorFilter(JNIEnv* env, jobject,
+ jlong colorFilterPtr, jstring childName,
+ jlong childFilterPtr) {
+ auto* filter = reinterpret_cast<RuntimeColorFilter*>(colorFilterPtr);
+ ScopedUtfChars name(env, childName);
+ auto* child = reinterpret_cast<ColorFilter*>(childFilterPtr);
+ if (filter && child) {
+ auto childInput = child->getInstance();
+ if (childInput) {
+ filter->updateChild(env, name.c_str(), childInput.release());
+ }
+ }
+ }
};
static const JNINativeMethod colorfilter_methods[] = {
@@ -193,7 +207,9 @@ static const JNINativeMethod runtime_color_filter_methods[] = {
{"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V",
(void*)ColorFilterGlue::RuntimeColorFilter_updateUniformsInts},
{"nativeUpdateChild", "(JLjava/lang/String;J)V",
- (void*)ColorFilterGlue::RuntimeColorFilter_updateChild}};
+ (void*)ColorFilterGlue::RuntimeColorFilter_updateChild},
+ {"nativeUpdateInputColorFilter", "(JLjava/lang/String;J)V",
+ (void*)ColorFilterGlue::RuntimeColorFilter_updateInputColorFilter}};
int register_android_graphics_ColorFilter(JNIEnv* env) {
android::RegisterMethodsOrDie(env, "android/graphics/ColorFilter", colorfilter_methods,
diff --git a/libs/hwui/jni/RuntimeXfermode.cpp b/libs/hwui/jni/RuntimeXfermode.cpp
index c1c8964bf5eb..17bee8fb8b15 100644
--- a/libs/hwui/jni/RuntimeXfermode.cpp
+++ b/libs/hwui/jni/RuntimeXfermode.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "ColorFilter.h"
#include "GraphicsJNI.h"
#include "RuntimeEffectUtils.h"
#include "SkBlender.h"
@@ -93,6 +94,19 @@ static void RuntimeXfermode_updateChild(JNIEnv* env, jobject, jlong builderPtr,
}
}
+static void RuntimeXfermode_updateColorFilter(JNIEnv* env, jobject, jlong builderPtr,
+ jstring childName, jlong colorFilterPtr) {
+ auto* builder = reinterpret_cast<SkRuntimeEffectBuilder*>(builderPtr);
+ ScopedUtfChars name(env, childName);
+ auto* child = reinterpret_cast<ColorFilter*>(colorFilterPtr);
+ if (child) {
+ auto childInput = child->getInstance();
+ if (childInput) {
+ UpdateChild(env, builder, name.c_str(), childInput.release());
+ }
+ }
+}
+
static const JNINativeMethod gRuntimeXfermodeMethods[] = {
{"nativeGetFinalizer", "()J", (void*)RuntimeXfermode_getNativeFinalizer},
{"nativeCreateBlenderBuilder", "(Ljava/lang/String;)J",
@@ -107,6 +121,8 @@ static const JNINativeMethod gRuntimeXfermodeMethods[] = {
{"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V",
(void*)RuntimeXfermode_updateIntUniforms},
{"nativeUpdateChild", "(JLjava/lang/String;J)V", (void*)RuntimeXfermode_updateChild},
+ {"nativeUpdateColorFilter", "(JLjava/lang/String;J)V",
+ (void*)RuntimeXfermode_updateColorFilter},
};
int register_android_graphics_RuntimeXfermode(JNIEnv* env) {
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index 018c2b1374d0..eadb9dea566f 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -1,5 +1,6 @@
#include <vector>
+#include "ColorFilter.h"
#include "Gainmap.h"
#include "GraphicsJNI.h"
#include "RuntimeEffectUtils.h"
@@ -331,6 +332,15 @@ static void RuntimeShader_updateShader(JNIEnv* env, jobject, jlong shaderBuilder
builder->child(name.c_str()) = sk_ref_sp(shader);
}
+static void RuntimeShader_updateColorFilter(JNIEnv* env, jobject, jlong shaderBuilder,
+ jstring jUniformName, jlong colorFilterHandle) {
+ SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
+ ScopedUtfChars name(env, jUniformName);
+ auto* childEffect = reinterpret_cast<ColorFilter*>(colorFilterHandle);
+
+ UpdateChild(env, builder, name.c_str(), childEffect->getInstance().release());
+}
+
static void RuntimeShader_updateChild(JNIEnv* env, jobject, jlong shaderBuilder,
jstring jUniformName, jlong childHandle) {
SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
@@ -380,6 +390,8 @@ static const JNINativeMethod gRuntimeShaderMethods[] = {
{"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V",
(void*)RuntimeShader_updateIntUniforms},
{"nativeUpdateShader", "(JLjava/lang/String;J)V", (void*)RuntimeShader_updateShader},
+ {"nativeUpdateColorFilter", "(JLjava/lang/String;J)V",
+ (void*)RuntimeShader_updateColorFilter},
{"nativeUpdateChild", "(JLjava/lang/String;J)V", (void*)RuntimeShader_updateChild},
};
diff --git a/media/java/android/media/AudioPlaybackConfiguration.java b/media/java/android/media/AudioPlaybackConfiguration.java
index c085b8985783..62fb0120a97d 100644
--- a/media/java/android/media/AudioPlaybackConfiguration.java
+++ b/media/java/android/media/AudioPlaybackConfiguration.java
@@ -311,12 +311,18 @@ public final class AudioPlaybackConfiguration implements Parcelable {
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public static final int MUTED_BY_PORT_VOLUME = (1 << 6);
+ /**
+ * @hide
+ * Flag used when playback is muted by AppOpsManager#OP_CONTROL_AUDIO.
+ */
+ public static final int MUTED_BY_OP_CONTROL_AUDIO = (1 << 7);
+
/** @hide */
@IntDef(
flag = true,
value = {MUTED_BY_MASTER, MUTED_BY_STREAM_VOLUME, MUTED_BY_STREAM_MUTED,
MUTED_BY_APP_OPS, MUTED_BY_CLIENT_VOLUME, MUTED_BY_VOLUME_SHAPER,
- MUTED_BY_PORT_VOLUME})
+ MUTED_BY_PORT_VOLUME, MUTED_BY_OP_CONTROL_AUDIO})
@Retention(RetentionPolicy.SOURCE)
public @interface PlayerMuteEvent {
}
@@ -914,6 +920,9 @@ public final class AudioPlaybackConfiguration implements Parcelable {
if ((mMutedState & MUTED_BY_PORT_VOLUME) != 0) {
apcToString.append("portVolume ");
}
+ if ((mMutedState & MUTED_BY_OP_CONTROL_AUDIO) != 0) {
+ apcToString.append("opControlAudio ");
+ }
}
apcToString.append(" ").append(mFormatInfo);
}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 08b0dd3fb11c..54a87ad7fd39 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -640,6 +640,9 @@ interface IAudioService {
boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af);
+ /* Returns a List<Integer> */
+ List getSpatializedChannelMasks();
+
void registerSpatializerCallback(in ISpatializerCallback cb);
void unregisterSpatializerCallback(in ISpatializerCallback cb);
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 4f94c3e984db..50387548b4ab 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -16,12 +16,12 @@
package android.media;
-
import static android.media.audio.Flags.FLAG_IAMF_DEFINITIONS_API;
+import static android.media.codec.Flags.FLAG_APV_SUPPORT;
import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC;
import static android.media.codec.Flags.FLAG_NUM_INPUT_SLOTS;
import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
-import static android.media.codec.Flags.FLAG_APV_SUPPORT;
+import static android.media.tv.flags.Flags.FLAG_APPLY_PICTURE_PROFILES;
import static com.android.media.codec.flags.Flags.FLAG_CODEC_IMPORTANCE;
import static com.android.media.codec.flags.Flags.FLAG_LARGE_AUDIO_FRAME;
@@ -1796,6 +1796,27 @@ public final class MediaFormat {
public static final String KEY_NUM_SLOTS = "num-slots";
/**
+ * A key describing the picture profile ID to be applied to {@link MediaCodec}.
+ * <p>
+ * The associated value is a string.
+ * <p>
+ * @see {@link android.media.quality.PictureProfile}
+ * @see {@link android.media.quality.PictureProfile#getProfileId}
+ */
+ @FlaggedApi(FLAG_APPLY_PICTURE_PROFILES)
+ public static final String KEY_PICTURE_PROFILE_ID = "picture-profile-id";
+
+ /**
+ * A key describing the picture profile instance to be applied to {@link MediaCodec}.
+ * <p>
+ * The associated value is an instance of {@link android.media.quality.PictureProfile}.
+ * <p>
+ * @see {@link android.media.quality.PictureProfile}
+ */
+ @FlaggedApi(FLAG_APPLY_PICTURE_PROFILES)
+ public static final String KEY_PICTURE_PROFILE_INSTANCE = "picture-profile-instance";
+
+ /**
* QpOffsetRect constitutes the metadata required for encoding a region of interest in an
* image or a video frame. The region of interest is represented by a rectangle. The four
* integer coordinates of the rectangle are stored in fields left, top, right, bottom.
diff --git a/media/java/android/media/Spatializer.java b/media/java/android/media/Spatializer.java
index 99fcaf29688c..95c4ad3c3a7f 100644
--- a/media/java/android/media/Spatializer.java
+++ b/media/java/android/media/Spatializer.java
@@ -16,7 +16,10 @@
package android.media;
+import static android.media.audio.Flags.FLAG_SPATIALIZER_CAPABILITIES;
+
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -35,6 +38,7 @@ import com.android.internal.annotations.GuardedBy;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -527,6 +531,28 @@ public class Spatializer {
}
/**
+ * Returns a list of channel masks that represent the widest channel masks the spatializer
+ * is capable of rendering with individual channel positions.
+ * For instance a spatializer may only support virtual speaker positions for 5.1, it would
+ * therefore return {@link AudioFormat#CHANNEL_OUT_5POINT1}. But it would still return
+ * <code>true</code> when querying {@link #canBeSpatialized(AudioAttributes, AudioFormat)} it
+ * with a channel mask of {@link AudioFormat#CHANNEL_OUT_7POINT1POINT2}: the sound present
+ * in each channel would still be heard, but the sounds from the rear, side and top pairs would
+ * be mixed together, and be spatialized at the same location.
+ * @return a list of channel masks following the <code>CHANNEL_OUT_*</code> output channel
+ * definitions found in {@link AudioFormat}.
+ */
+ @FlaggedApi(FLAG_SPATIALIZER_CAPABILITIES)
+ public @NonNull List<Integer> getSpatializedChannelMasks() {
+ try {
+ return mAm.getService().getSpatializedChannelMasks();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error querying getSpatializedChannelMasks", e);
+ return Collections.emptyList();
+ }
+ }
+
+ /**
* Adds a listener to be notified of changes to the enabled state of the
* {@code Spatializer}.
* @param executor the {@code Executor} handling the callback
diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig
index d8a8c8b0ee2a..bbe8e4ed7b34 100644
--- a/media/java/android/media/flags/media_better_together.aconfig
+++ b/media/java/android/media/flags/media_better_together.aconfig
@@ -141,6 +141,14 @@ flag {
}
flag {
+ name: "enable_route_visibility_control_api"
+ namespace: "media_better_together"
+ description: "API changes to allow more control over route visibility by route providers"
+ bug: "367799834"
+ is_exported: true
+}
+
+flag {
name: "enable_screen_off_scanning"
is_exported: true
namespace: "media_solutions"
diff --git a/media/java/android/media/projection/IMediaProjection.aidl b/media/java/android/media/projection/IMediaProjection.aidl
index 8ee966ddc377..dacd1bd06cc0 100644
--- a/media/java/android/media/projection/IMediaProjection.aidl
+++ b/media/java/android/media/projection/IMediaProjection.aidl
@@ -17,13 +17,14 @@
package android.media.projection;
import android.media.projection.IMediaProjectionCallback;
+import android.media.projection.StopReason;
import android.os.IBinder;
import android.app.ActivityOptions.LaunchCookie;
/** {@hide} */
interface IMediaProjection {
void start(IMediaProjectionCallback callback);
- void stop();
+ void stop(StopReason stopReason);
boolean canProjectAudio();
boolean canProjectVideo();
diff --git a/media/java/android/media/projection/IMediaProjectionManager.aidl b/media/java/android/media/projection/IMediaProjectionManager.aidl
index b104972572b9..1d92eabb726d 100644
--- a/media/java/android/media/projection/IMediaProjectionManager.aidl
+++ b/media/java/android/media/projection/IMediaProjectionManager.aidl
@@ -16,11 +16,13 @@
package android.media.projection;
+import android.graphics.Rect;
import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionCallback;
import android.media.projection.IMediaProjectionWatcherCallback;
import android.media.projection.MediaProjectionInfo;
import android.media.projection.ReviewGrantedConsentResult;
+import android.media.projection.StopReason;
import android.os.IBinder;
import android.view.ContentRecordingSession;
@@ -107,12 +109,7 @@ interface IMediaProjectionManager {
@EnforcePermission("MANAGE_MEDIA_PROJECTION")
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ ".permission.MANAGE_MEDIA_PROJECTION)")
- void stopActiveProjection();
-
- @EnforcePermission("MANAGE_MEDIA_PROJECTION")
- @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
- + ".permission.MANAGE_MEDIA_PROJECTION)")
- void notifyActiveProjectionCapturedContentResized(int width, int height);
+ void stopActiveProjection(in StopReason stopReason);
@EnforcePermission("MANAGE_MEDIA_PROJECTION")
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
@@ -227,5 +224,11 @@ interface IMediaProjectionManager {
@EnforcePermission("MANAGE_MEDIA_PROJECTION")
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ ".permission.MANAGE_MEDIA_PROJECTION)")
- void notifyWindowingModeChanged(int contentToRecord, int targetProcessUid, int windowingMode);
+ oneway void notifyWindowingModeChanged(int contentToRecord, int targetProcessUid, int windowingMode);
+
+ @EnforcePermission("MANAGE_MEDIA_PROJECTION")
+ @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ + ".permission.MANAGE_MEDIA_PROJECTION)")
+ oneway void notifyCaptureBoundsChanged(int contentToRecord, int targetProcessUid,
+ in Rect captureBounds);
}
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index 4114f5359ace..f7f10df5786a 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -317,7 +317,7 @@ public final class MediaProjection {
public void stop() {
try {
Log.d(TAG, "Content Recording: stopping projection");
- mImpl.stop();
+ mImpl.stop(StopReason.STOP_HOST_APP);
} catch (RemoteException e) {
Log.e(TAG, "Unable to stop projection", e);
}
diff --git a/media/java/android/media/projection/MediaProjectionManager.java b/media/java/android/media/projection/MediaProjectionManager.java
index dc55e41fb74c..9cc2cca441a4 100644
--- a/media/java/android/media/projection/MediaProjectionManager.java
+++ b/media/java/android/media/projection/MediaProjectionManager.java
@@ -297,10 +297,10 @@ public final class MediaProjectionManager {
* Stop the current projection if there is one.
* @hide
*/
- public void stopActiveProjection() {
+ public void stopActiveProjection(@StopReason int stopReason) {
try {
Log.d(TAG, "Content Recording: stopping active projection");
- mService.stopActiveProjection();
+ mService.stopActiveProjection(stopReason);
} catch (RemoteException e) {
Log.e(TAG, "Unable to stop the currently active media projection", e);
}
diff --git a/media/java/android/media/projection/StopReason.aidl b/media/java/android/media/projection/StopReason.aidl
new file mode 100644
index 000000000000..8611def3d2b9
--- /dev/null
+++ b/media/java/android/media/projection/StopReason.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.projection;
+
+/**
+ * Identifies the reason for a MediaProjection being stopped (for metric logging purposes)
+ * @hide
+ */
+@Backing(type="int")
+enum StopReason {
+ STOP_UNKNOWN = 0,
+ STOP_HOST_APP = 1,
+ STOP_TARGET_REMOVED = 2,
+ STOP_DEVICE_LOCKED = 3,
+ STOP_PRIVACY_CHIP = 4,
+ STOP_QS_TILE = 5,
+ STOP_USER_SWITCH = 6,
+ STOP_FOREGROUND_SERVICE_CHANGE = 7,
+ STOP_NEW_PROJECTION = 8,
+ STOP_NEW_MEDIA_ROUTE = 9,
+ STOP_ERROR = 10,
+}
diff --git a/media/java/android/media/tv/extension/analog/IAnalogAttributeInterface.aidl b/media/java/android/media/tv/extension/analog/IAnalogAttributeInterface.aidl
new file mode 100644
index 000000000000..550acba8ed65
--- /dev/null
+++ b/media/java/android/media/tv/extension/analog/IAnalogAttributeInterface.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.analog;
+
+/**
+ * @hide
+ */
+interface IAnalogAttributeInterface {
+ int getVersion();
+ void setColorSystemCapability(in String[] list);
+ String[] getColorSystemCapability();
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamAppInfoListener.aidl b/media/java/android/media/tv/extension/cam/ICamAppInfoListener.aidl
new file mode 100644
index 000000000000..73ae209062d6
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamAppInfoListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ICamAppInfoListener {
+ void onCamAppInfoChanged(int slotId, in Bundle appInfo);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamAppInfoService.aidl b/media/java/android/media/tv/extension/cam/ICamAppInfoService.aidl
new file mode 100644
index 000000000000..d3a03bc80056
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamAppInfoService.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamAppInfoListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ICamAppInfoService {
+ // Register ICamAppInfoListener to get CICAM Application Information updates.
+ void addCamAppInfoListener(ICamAppInfoListener listener);
+ // Unregister ICamAppInfoListener and stop get Application Information notify.
+ void removeCamAppInfoListener(ICamAppInfoListener listener);
+ // Get the Application Information of the CICAM.
+ int getCamAppInfo(int slotId, out Bundle appInfo);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamDrmInfoListener.aidl b/media/java/android/media/tv/extension/cam/ICamDrmInfoListener.aidl
new file mode 100644
index 000000000000..c727837ed07e
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamDrmInfoListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ICamDrmInfoListener {
+ void onCamDrmInfoChanged(int slotId, in Bundle camDrmInfo);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamHostControlAskReleaseReplyCallback.aidl b/media/java/android/media/tv/extension/cam/ICamHostControlAskReleaseReplyCallback.aidl
new file mode 100644
index 000000000000..83f2c01e4681
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamHostControlAskReleaseReplyCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.cam;
+
+/**
+ * @hide
+ */
+oneway interface ICamHostControlAskReleaseReplyCallback {
+ void onAskReleaseReply(String sessionToken, int replyStatus);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamHostControlInfoListener.aidl b/media/java/android/media/tv/extension/cam/ICamHostControlInfoListener.aidl
new file mode 100644
index 000000000000..f48ca57cccdc
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamHostControlInfoListener.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.cam;
+
+/**
+ * @hide
+ */
+oneway interface ICamHostControlInfoListener {
+ void onCamHostControlInfoChanged(String sessionToken, int sessionStatus);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamHostControlService.aidl b/media/java/android/media/tv/extension/cam/ICamHostControlService.aidl
new file mode 100644
index 000000000000..6f6c376c1ffa
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamHostControlService.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamHostControlAskReleaseReplyCallback;
+import android.media.tv.extension.cam.ICamHostControlInfoListener;
+
+/**
+ * @hide
+ */
+interface ICamHostControlService {
+ // Register the listener to monitor host control session updates.
+ void addCamHostcontrolInfoListener(ICamHostControlInfoListener listener);
+ // Unregister ICamHostControlInfoListener and stop monitoring.
+ void removeCamHostcontrolInfoListener(ICamHostControlInfoListener listener);
+ // Request CICAM to release the resource.
+ int sendCamHostControlAskRelease(String sessionToken,
+ ICamHostControlAskReleaseReplyCallback callback);
+ // Enable/disable the host control mode.
+ void setHostControlMode(String sessionToken, boolean enable);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlag.aidl b/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlag.aidl
new file mode 100644
index 000000000000..25a78b99d659
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlag.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamHostControlTuneQuietlyFlagListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ICamHostControlTuneQuietlyFlag {
+ // Register listener to notify host control tune_quietly_flag.
+ void addHcTuneQuietlyFlagListener(ICamHostControlTuneQuietlyFlagListener listener);
+ // Remove listener and stop monitor host control tune_quietly_flag.
+ void removeHcTuneQuietlyFlagListener(ICamHostControlTuneQuietlyFlagListener listener);
+ // Returns host control tune_quietly_flag value.
+ Bundle getHcTuneQuietlyFlag(String sessionToken);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlagListener.aidl b/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlagListener.aidl
new file mode 100644
index 000000000000..5967124e5202
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamHostControlTuneQuietlyFlagListener.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.cam;
+
+/**
+ * @hide
+ */
+oneway interface ICamHostControlTuneQuietlyFlagListener {
+ void onHcTuneQuietlyFlagChanged(String sessionToken, int tuneQuietlyFlag);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamInfoListener.aidl b/media/java/android/media/tv/extension/cam/ICamInfoListener.aidl
new file mode 100644
index 000000000000..5410bffaa92d
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamInfoListener.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ICamInfoListener {
+ void onCamInfoChanged(int slotId, in Bundle updatedCamInfo);
+ void onSlotInfoChanged(int slotId, in Bundle updatedSlotInfo);
+ void onNewTypeCamInsert(int slotId, in Bundle newCamType);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamMonitoringService.aidl b/media/java/android/media/tv/extension/cam/ICamMonitoringService.aidl
new file mode 100644
index 000000000000..7b8014c5880f
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamMonitoringService.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamInfoListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ICamMonitoringService {
+ // Register a listener for slot/CAM info updates.
+ void addCamInfoListener(in ICamInfoListener listener);
+ // Unregister a listener for slot/CAM info updates.
+ void removeCamInfoListener(in ICamInfoListener listener);
+ // Get CAM information for the specified slot.
+ Bundle getCamInfo(int slotId);
+ // Get slot information.
+ Bundle getSlotInfo(int slotId);
+ // Returns list of slot Ids.
+ int[] getSlotIds();
+ // Check if the country supports CAM.
+ boolean isCamSupported();
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamPinCapabilityListener.aidl b/media/java/android/media/tv/extension/cam/ICamPinCapabilityListener.aidl
new file mode 100644
index 000000000000..f92304af9ade
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamPinCapabilityListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ICamPinCapabilityListener {
+ void onCamPinCapabilityChanged(int slotId, in Bundle bundle);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamPinService.aidl b/media/java/android/media/tv/extension/cam/ICamPinService.aidl
new file mode 100644
index 000000000000..3f6cb2813c74
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamPinService.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamPinCapabilityListener;
+import android.media.tv.extension.cam.ICamPinStatusListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ICamPinService {
+ // Register ICamPinCapabilityListener to get CICAM updates.
+ void addCamPinCapabilityListener(in ICamPinCapabilityListener listener);
+ // Unregister ICamPinCapabilityListener and stop monitor PIN status and PIN capability.
+ void removeCamPinCapabilityListener(in ICamPinCapabilityListener listener);
+ // Send the PinCode that needs to be validated by CICAM.
+ int requestCamPinValidation(int slotId, in int[] pinCode, in ICamPinStatusListener listener);
+ // Get the PIN capabilities of the CICAM.
+ int getCamPinCapability(int slotId, out Bundle camPinCapability);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamPinStatusListener.aidl b/media/java/android/media/tv/extension/cam/ICamPinStatusListener.aidl
new file mode 100644
index 000000000000..efbc394897d3
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamPinStatusListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ICamPinStatusListener {
+ void onCamPinValidationReply(int slotId, in Bundle bundle);
+}
diff --git a/media/java/android/media/tv/extension/cam/ICamProfileInterface.aidl b/media/java/android/media/tv/extension/cam/ICamProfileInterface.aidl
new file mode 100644
index 000000000000..3f1d40caa9c9
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/ICamProfileInterface.aidl
@@ -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 android.media.tv.extension.cam;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ICamProfileInterface {
+ // Get CAM service update information for special slot.
+ Bundle getCamServiceUpdateInfo(int slotNumber);
+ // Request CAM TIS resend cam info update broadcast message when APK boot up.
+ void requestResendProfileInfoBroadcastACON();
+}
diff --git a/media/java/android/media/tv/extension/cam/IContentControlService.aidl b/media/java/android/media/tv/extension/cam/IContentControlService.aidl
new file mode 100644
index 000000000000..6db79abacb76
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/IContentControlService.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.ICamDrmInfoListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IContentControlService {
+ // Register the listener to notify the DRM info changed by the CICAM.
+ void addCamDrmInfoListener(in ICamDrmInfoListener listener);
+ // Unregister listener to stop monitor DRM Info.
+ void removeCamDrmInfoListener(in ICamDrmInfoListener listener);
+ // Get the DRM Info of current watching channel.
+ int getCamDrmInfo(int slotId, out Bundle camDrmInfo);
+}
diff --git a/media/java/android/media/tv/extension/cam/IEnterMenuErrorCallback.aidl b/media/java/android/media/tv/extension/cam/IEnterMenuErrorCallback.aidl
new file mode 100644
index 000000000000..ff61ddcbcc2f
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/IEnterMenuErrorCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.cam;
+
+/**
+ * @hide
+ */
+oneway interface IEnterMenuErrorCallback {
+ void onAppInfoEnterMenuError();
+}
diff --git a/media/java/android/media/tv/extension/cam/IMmiInterface.aidl b/media/java/android/media/tv/extension/cam/IMmiInterface.aidl
new file mode 100644
index 000000000000..17a2a9c6771f
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/IMmiInterface.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.media.tv.extension.cam.IEnterMenuErrorCallback;
+import android.media.tv.extension.cam.IMmiSession;
+import android.media.tv.extension.cam.IMmiStatusCallback;
+
+
+/**
+ * @hide
+ */
+interface IMmiInterface {
+ // Open a session for MMI.
+ IMmiSession openSession(int slotId, IMmiStatusCallback callback);
+ // Request to display CI Module setup screen.
+ void appInfoEnterMenu(int slotId, IEnterMenuErrorCallback callback);
+}
diff --git a/media/java/android/media/tv/extension/cam/IMmiSession.aidl b/media/java/android/media/tv/extension/cam/IMmiSession.aidl
new file mode 100644
index 000000000000..c4f276219c55
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/IMmiSession.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.media.tv.extension.cam;
+
+/**
+ * @hide
+ */
+interface IMmiSession {
+ // Send user answers to CAM on the MMI Menu screen.
+ void setMenuListAnswer(int response);
+ // Send user answers to CAM on the MMI Enq screen.
+ void setEnquiryAnswer(int answerId, String answer);
+ // Send CloseMmi APDU to Cam.
+ void closeMmi();
+ // Release MMI session.
+ void close();
+}
diff --git a/media/java/android/media/tv/extension/cam/IMmiStatusCallback.aidl b/media/java/android/media/tv/extension/cam/IMmiStatusCallback.aidl
new file mode 100644
index 000000000000..3e68ced6a1ce
--- /dev/null
+++ b/media/java/android/media/tv/extension/cam/IMmiStatusCallback.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.media.tv.extension.cam;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IMmiStatusCallback {
+ void onMmiEnq(in Bundle request);
+ void onMmiListMenu(in Bundle request);
+ void onMmiClose();
+}
diff --git a/media/java/android/media/tv/extension/clienttoken/IClientToken.aidl b/media/java/android/media/tv/extension/clienttoken/IClientToken.aidl
new file mode 100644
index 000000000000..fa701b3c01ad
--- /dev/null
+++ b/media/java/android/media/tv/extension/clienttoken/IClientToken.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.clienttoken;
+
+/**
+ * @hide
+ */
+interface IClientToken {
+ String generateClientToken();
+}
diff --git a/media/java/android/media/tv/extension/event/IEventDownload.aidl b/media/java/android/media/tv/extension/event/IEventDownload.aidl
new file mode 100644
index 000000000000..29c7553e1014
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventDownload.aidl
@@ -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 android.media.tv.extension.event;
+
+import android.media.tv.extension.event.IEventDownloadListener;
+import android.os.Bundle;
+import android.os.IBinder;
+
+/**
+ * @hide
+ */
+interface IEventDownload {
+ // Create an event download session and return it as a Ibinder for DVB/DTMB
+ IBinder createSession(in Bundle eventDownloadParams, in IEventDownloadListener listener);
+}
diff --git a/media/java/android/media/tv/extension/event/IEventDownloadListener.aidl b/media/java/android/media/tv/extension/event/IEventDownloadListener.aidl
new file mode 100644
index 000000000000..6d7d61f15d27
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventDownloadListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.event;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IEventDownloadListener {
+ void onCompleted(in Bundle status);
+}
diff --git a/media/java/android/media/tv/extension/event/IEventDownloadSession.aidl b/media/java/android/media/tv/extension/event/IEventDownloadSession.aidl
new file mode 100644
index 000000000000..fe7ee37b324b
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventDownloadSession.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.extension.event;
+
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IEventDownloadSession {
+ // Determine to execute barker channel or silent tune flow for related service type
+ int isBarkerOrSequentialDownloadByServiceType(in Bundle eventDownloadParams);
+ // Determine whether to start barker channel or silent tune flow.
+ int isBarkerOrSequentialDownloadByServiceRecord(in Bundle eventDownloadParams);
+ // Start event download.
+ void startTuningMultiplex(in Uri channelUri);
+ // Set active window channels.
+ void setActiveWindowChannelInfo(in Uri[] activeWinChannelInfos);
+ // Cancel barker channel or silent tune flow.
+ void cancel();
+ // Release barker channel or silent tune flow.
+ void release();
+}
diff --git a/media/java/android/media/tv/extension/event/IEventMonitor.aidl b/media/java/android/media/tv/extension/event/IEventMonitor.aidl
new file mode 100644
index 000000000000..f6e7bd134e78
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventMonitor.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.media.tv.extension.event;
+
+import android.media.tv.extension.event.IEventMonitorListener;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IEventMonitor {
+ // Get present event information.
+ Bundle getPresentEventInfo(long channelDbId);
+ // Add present event information listener.
+ void addPresentEventInfoListener(in IEventMonitorListener listener);
+ // Remove present event information listener.
+ void removePresentEventInfoListener(in IEventMonitorListener listener);
+ // Get following event information.
+ Bundle getFollowingEventInfo(long channelDbId);
+ // Add following event information listener.
+ void addFollowingEventInfoListener(in IEventMonitorListener listener);
+ // Remove following event information listener.
+ void removeFollowingEventInfoListener(in IEventMonitorListener listener);
+ // Get SDT guidance information.
+ Bundle getSdtGuidanceInfo(long channelDbId);
+ // Set Event Background channel list info.
+ void setBgmTuneChannelInfo(in Uri[] tuneChannelInfos);
+}
diff --git a/media/java/android/media/tv/extension/event/IEventMonitorListener.aidl b/media/java/android/media/tv/extension/event/IEventMonitorListener.aidl
new file mode 100644
index 000000000000..a00e5422a7e0
--- /dev/null
+++ b/media/java/android/media/tv/extension/event/IEventMonitorListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.event;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IEventMonitorListener {
+ void onInfoChanged(long channelDbId, in Bundle eventinfo);
+}
diff --git a/media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl b/media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl
new file mode 100644
index 000000000000..ff78aa4be39c
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IFavoriteNetwork.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.IFavoriteNetworkListener;
+import android.os.Bundle;
+
+/**
+ * Country: Norway
+ * Broadcast Type: BROADCAST_TYPE_DVB_T
+ * (Operator: RiksTV)
+ *
+ * @hide
+ */
+interface IFavoriteNetwork {
+ // Get the favorite network information,If there are no conflicts, the array of Bundle is empty.
+ Bundle[] getFavoriteNetworks();
+ // Select and set one of two or more favorite networks detected by the service scan.
+ int setFavoriteNetwork(in Bundle favoriteNetworkSettings);
+ // Set the listener to be invoked when two or more favorite networks are detected.
+ int setListener(in IFavoriteNetworkListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/IFavoriteNetworkListener.aidl b/media/java/android/media/tv/extension/scan/IFavoriteNetworkListener.aidl
new file mode 100644
index 000000000000..699422493dd6
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IFavoriteNetworkListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IFavoriteNetworkListener {
+ void onDetectFavoriteNetwork(in Bundle detectFavoriteNetworks);
+}
diff --git a/media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl b/media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl
new file mode 100644
index 000000000000..cdf6e23f4b47
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IHDPlusInfo.aidl
@@ -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.
+ */
+
+package android.media.tv.extension.scan;
+
+/**
+ * @hide
+ */
+interface IHDPlusInfo {
+ // Specifying a HDPlusInfo and start a network scan.
+ int setHDPlusInfo(String isBlindScanContinue, String isHDMode);
+}
diff --git a/media/java/android/media/tv/extension/scan/ILcnConflict.aidl b/media/java/android/media/tv/extension/scan/ILcnConflict.aidl
new file mode 100644
index 000000000000..5dff39eb5920
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ILcnConflict.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.ILcnConflictListener;
+import android.os.Bundle;
+
+/**
+ * Country: Italy, France
+ * Broadcast Type: BROADCAST_TYPE_DVB_T
+ *
+ * @hide
+ */
+interface ILcnConflict {
+ // Get the LCN conflict groups information, If there are no conflicts, the array of Bundle is empty.
+ Bundle[] getLcnConflictGroups();
+ // Resolve LCN conflicts caused by service scans.
+ int resolveLcnConflict(in Bundle[] lcnConflictSettings);
+ // Set the listener to be invoked the LCN conflict event.
+ int setListener(in ILcnConflictListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/ILcnConflictListener.aidl b/media/java/android/media/tv/extension/scan/ILcnConflictListener.aidl
new file mode 100644
index 000000000000..6bbbeb8e1e06
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ILcnConflictListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ILcnConflictListener {
+ void onDetectLcnConflict(in Bundle detectLcnConflicts);
+}
diff --git a/media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl b/media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl
new file mode 100644
index 000000000000..f9a9d345a575
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ILcnV2ChannelList.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.ILcnV2ChannelListListener;
+import android.os.Bundle;
+
+/**
+ * Country: (NorDig etc.)
+ * Broadcast Type: BROADCAST_TYPE_DVB_T, BROADCAST_TYPE_DVB_C
+ *
+ * @hide
+ */
+interface ILcnV2ChannelList {
+ // Get the LCN V2 channel list information. If there are no conflicts, the array of Bundle is empty.
+ Bundle[] getLcnV2ChannelLists();
+ // Select and set one of two or more LCN V2 channel list detected by the service scan.
+ int setLcnV2ChannelList(in Bundle lcnV2ChannelListSettings);
+ // Set the listener to be invoked when two or more LCN V2 channel list are detected.
+ int setListener(in ILcnV2ChannelListListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/ILcnV2ChannelListListener.aidl b/media/java/android/media/tv/extension/scan/ILcnV2ChannelListListener.aidl
new file mode 100644
index 000000000000..cbdb83c656f4
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ILcnV2ChannelListListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ILcnV2ChannelListListener {
+ void onDetectLcnV2ChannelList(in Bundle detectLcnV2ChannelList);
+}
diff --git a/media/java/android/media/tv/extension/scan/IOperatorDetection.aidl b/media/java/android/media/tv/extension/scan/IOperatorDetection.aidl
new file mode 100644
index 000000000000..770f8668983e
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IOperatorDetection.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.IOperatorDetectionListener;
+import android.os.Bundle;
+
+/**
+ * Country: Any
+ * Broadcast Type: BROADCAST_TYPE_DVB_S
+ * (Operator: M7)
+ *
+ * @hide
+ */
+interface IOperatorDetection {
+ // Set the operator selected info for scanning.
+ int setOperatorDetection(in Bundle operatorSelected);
+ // Set the listener to be invoked when one or more operator detection has been detected by
+ // operator detection searches.
+ int setListener(in IOperatorDetectionListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/IOperatorDetectionListener.aidl b/media/java/android/media/tv/extension/scan/IOperatorDetectionListener.aidl
new file mode 100644
index 000000000000..7dcd46177c43
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IOperatorDetectionListener.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+
+/**
+ * @hide
+ */
+oneway interface IOperatorDetectionListener {
+ void onDetectOperatorDetectionList(in Bundle[] detectOperatorDetectionList);
+}
diff --git a/media/java/android/media/tv/extension/scan/IRegionChannelList.aidl b/media/java/android/media/tv/extension/scan/IRegionChannelList.aidl
new file mode 100644
index 000000000000..fe755f873110
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IRegionChannelList.aidl
@@ -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 android.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.IRegionChannelListListener;
+
+/**
+ * @hide
+ */
+interface IRegionChannelList {
+ // Set the region channel list for scanning.
+ int setRegionChannelList(String regionChannelList);
+ // Set the listener to be invoked when one or more region channel list has been detected by
+ // region channel list searches.
+ int setListener(in IRegionChannelListListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl b/media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl
new file mode 100644
index 000000000000..06b0eb5537a2
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IRegionChannelListListener.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.scan;
+
+/**
+ * @hide
+ */
+oneway interface IRegionChannelListListener {
+ void onDetectRegionChannelList(in String[] detectRegionChannelList);
+}
diff --git a/media/java/android/media/tv/extension/scan/IScanInterface.aidl b/media/java/android/media/tv/extension/scan/IScanInterface.aidl
new file mode 100644
index 000000000000..b44d1d243150
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IScanInterface.aidl
@@ -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 android.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.IScanListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IScanInterface {
+ IBinder createSession(int broadcastType, String countryCode, String operator,
+ in IScanListener listener);
+ Bundle getParameters(int broadcastType, String countryCode, String operator,
+ in Bundle params);
+}
diff --git a/media/java/android/media/tv/extension/scan/IScanListener.aidl b/media/java/android/media/tv/extension/scan/IScanListener.aidl
new file mode 100644
index 000000000000..2c4807f97c58
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IScanListener.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IScanListener {
+ // notify events during scan.
+ void onEvent(in Bundle eventArgs);
+ // notify the scan progress.
+ void onScanProgress(String scanProgress, in Bundle scanProgressInfo);
+ // notify the scan completion.
+ void onScanCompleted(int scanResult);
+ // notify that the temporaily held channel list is stored.
+ void onStoreCompleted(int storeResult);
+}
diff --git a/media/java/android/media/tv/extension/scan/IScanSatSearch.aidl b/media/java/android/media/tv/extension/scan/IScanSatSearch.aidl
new file mode 100644
index 000000000000..b8074fc4a9bd
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IScanSatSearch.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+/**
+ * For satellite search function.
+ * @hide
+ */
+interface IScanSatSearch {
+ // Set currecnt LNB as customized LNB, default LNB is universal LNB
+ int setCustomizedLnb(String customizedLnb);
+}
diff --git a/media/java/android/media/tv/extension/scan/IScanSession.aidl b/media/java/android/media/tv/extension/scan/IScanSession.aidl
new file mode 100644
index 000000000000..d42eca1342b5
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/IScanSession.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IScanSession {
+ // Start a service scan.
+ int startScan(int broadcastType, String countryCode, String operator, in int[] frequency,
+ String scanType, String languageCode);
+ // Reset the scan information held in TIS.
+ int resetScan();
+ // Cancel scan.
+ int cancelScan();
+
+ // Get available interface for created ScanExtension interface.
+ String[] getAvailableExtensionInterfaceNames();
+ // Get extension interface for Scan.
+ IBinder getExtensionInterface(String name);
+
+ // Clear the results of the service scan from the service database.
+ int clearServiceList(in Bundle optionalClearParams);
+ // Store the results of the service scan from the service database.
+ int storeServiceList();
+ // Get a service information specified by the service information ID.
+ Bundle getServiceInfo(String serviceInfoId, in String[] keys);
+ // Get a service information ID list.
+ String[] getServiceInfoIdList();
+ // Get a list of service info by the filter.
+ Bundle getServiceInfoList(in Bundle filterInfo, in String[] keys);
+ // Update the service information.
+ int updateServiceInfo(in Bundle serviceInfo);
+ // Updates the service information for the specified service information ID in array list.
+ int updateServiceInfoByList(in Bundle[] serviceInfo);
+
+ /* DVBI specific functions */
+ // Get all of the serviceLists, parsed from Local TV storage, Broadcast, USB file discovery.
+ Bundle getServiceLists();
+ // Users choose one serviceList from the serviceLists, and install the services.
+ int setServiceList(int serviceListRecId);
+ // Get all of the packageData, parsed from the selected serviceList XML.
+ Bundle getPackageData();
+ // Choose the package using package id and install the corresponding services.
+ int setPackage(String packageId);
+ // Get all of the countryRegionData, parsed from the selected serviceList XML.
+ Bundle getCountryRegionData();
+ // Choose the countryRegion using countryRegion id, and install the corresponding services.
+ int setCountryRegion(String regionId);
+ // Get all of the regionData, parsed from the selected serviceList XML.
+ Bundle getRegionData();
+ // Choose the region using the regionData id, and install the corresponding services.
+ int setRegion(String regionId);
+
+ // Get unique session token for the scan.
+ String getSessionToken();
+ // Release scan resource, the register listener will be released.
+ int release();
+}
diff --git a/media/java/android/media/tv/extension/scan/ITargetRegion.aidl b/media/java/android/media/tv/extension/scan/ITargetRegion.aidl
new file mode 100644
index 000000000000..417e12243b82
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ITargetRegion.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.ITargetRegionListener;
+
+import android.os.Bundle;
+
+/**
+ * Country: U.K.
+ * Broadcast Type: BROADCAST_TYPE_DVB_T
+ *
+ * @hide
+ */
+interface ITargetRegion {
+ // Get the target regions information. If there are no conflicts, the array of Bundle is empty.
+ Bundle[] getTargetRegions();
+ // Select and set one of two or more target region detected by the service scan.
+ int setTargetRegion(in Bundle targetRegionSettings);
+ // Set the listener to be invoked when two or more regions are detected.
+ int setListener(in ITargetRegionListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl b/media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl
new file mode 100644
index 000000000000..9d6aa8e8ea31
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ITargetRegionListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface ITargetRegionListener {
+ void onDetectTargetRegion(in Bundle detectTargetRegions);
+}
diff --git a/media/java/android/media/tv/extension/scan/ITkgsInfo.aidl b/media/java/android/media/tv/extension/scan/ITkgsInfo.aidl
new file mode 100644
index 000000000000..f25952c1cbdc
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ITkgsInfo.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.media.tv.extension.scan;
+
+import android.media.tv.extension.scan.ITkgsInfoListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ITkgsInfo {
+ int setPrefServiceList(String prefServiceList);
+ int setTkgsInfoListener(in ITkgsInfoListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl b/media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl
new file mode 100644
index 000000000000..e3dcf2d4c5ad
--- /dev/null
+++ b/media/java/android/media/tv/extension/scan/ITkgsInfoListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.scan;
+
+/**
+ * @hide
+ */
+oneway interface ITkgsInfoListener {
+ void onServiceList(in String[] serviceList);
+ void onTableVersionUpdate(int tableVersion);
+ void onUserMessage(String strMessage);
+}
diff --git a/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdate.aidl b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdate.aidl
new file mode 100644
index 000000000000..bda60edc48c1
--- /dev/null
+++ b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdate.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.media.tv.extension.scanbsu;
+
+import android.media.tv.extension.scanbsu.IScanBackgroundServiceUpdateListener;
+
+/**
+ * @hide
+ */
+interface IScanBackgroundServiceUpdate {
+ // Set the listener for background service update
+ // receives notifications for svl/tsl/nwl update during background service update.
+ void addBackgroundServiceUpdateListener(String clientToken,
+ in IScanBackgroundServiceUpdateListener listener);
+ // Remove the listener for background service update to stop receiving notifications
+ // for svl/tsl/nwl update during background service update.
+ void removeBackgroundServiceUpdateListener(in IScanBackgroundServiceUpdateListener listener);
+}
diff --git a/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdateListener.aidl b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdateListener.aidl
new file mode 100644
index 000000000000..d9bcbedb234a
--- /dev/null
+++ b/media/java/android/media/tv/extension/scanbsu/IScanBackgroundServiceUpdateListener.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.media.tv.extension.scanbsu;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IScanBackgroundServiceUpdateListener {
+ // On background service update add/delete/update svl records.
+ void onChannelListUpdate(String sessionToken, out Bundle[] updateInfos);
+ // On background service update add/delete/update nwl records.
+ void onNetworkListUpdate(String sessionToken, out Bundle[] updateInfos);
+ // On background service update add/delete/update tsl records.
+ void onTransportStreamingListUpdate(String sessionToken, out Bundle[] updateInfos);
+}
diff --git a/media/java/android/media/tv/extension/screenmode/IScreenModeSettings.aidl b/media/java/android/media/tv/extension/screenmode/IScreenModeSettings.aidl
new file mode 100644
index 000000000000..57f3b4ab5017
--- /dev/null
+++ b/media/java/android/media/tv/extension/screenmode/IScreenModeSettings.aidl
@@ -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 android.media.tv.extension.screenmode;
+
+/**
+ * @hide
+ */
+interface IScreenModeSettings {
+ // Set screen mode information using a JSON string.
+ void setScreenModeSettings(String sessionToken, String setting);
+ // Get the overscan index which TIS session is applied.
+ int getOverScanIndex(String sessionToken);
+ // Get status that TIS session is support overscan or not.
+ boolean getSupportApplyOverScan(String sessionToken);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IChannelListTransfer.aidl b/media/java/android/media/tv/extension/servicedb/IChannelListTransfer.aidl
new file mode 100644
index 000000000000..cb6aeccb5b57
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IChannelListTransfer.aidl
@@ -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 android.media.tv.extension.servicedb;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * @hide
+ */
+interface IChannelListTransfer {
+ // Parse XML file and import Channels information.
+ void importChannelList(in ParcelFileDescriptor pfd);
+ // Get Channels information for export and create XML file.
+ void exportChannelList(in ParcelFileDescriptor pfd);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceList.aidl b/media/java/android/media/tv/extension/servicedb/IServiceList.aidl
new file mode 100644
index 000000000000..51daa80ccbd6
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceList.aidl
@@ -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 android.media.tv.extension.servicedb;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IServiceList {
+ // Get a list of the Service list IDs quivalent to COLUMN_CHANNEL_LIST_ID
+ // in the Channels table of TvProvider.
+ String[] getServiceListIds();
+ // Get the information associated with the Service list.
+ Bundle getServiceListInfo(String serviceListId, in String[] keys);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListEdit.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListEdit.aidl
new file mode 100644
index 000000000000..1b1577ffc015
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListEdit.aidl
@@ -0,0 +1,81 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+import android.media.tv.extension.servicedb.IServiceListEditListener;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IServiceListEdit {
+ // Open in edit mode. Must call close() after edit is done.
+ int open(IServiceListEditListener listener);
+ // Method to close in edit mode.
+ int close();
+ // Method to commit changes made to service database.
+ int commit();
+ // Method to commit and close the changes.
+ int userEditCommit();
+
+ // Get a service/transportStream/Network/Satellite record information specified by
+ // serviceInfoId and keys from tvdb.
+ Bundle getServiceInfoFromDatabase(String serviceInfoId, in String[] keys);
+ // Get a list of all service records' information specified by serviceListId and keys from tvdb.
+ Bundle getServiceInfoListFromDatabase(String serviceListId, in String[] keys);
+ // Get a list of all service info IDs in the service list of serviceListId from tvdb.
+ String[] getServiceInfoIdsFromDatabase(String inServiceListId);
+ // Update a service information by the contents of serviceInfo;
+ int updateServiceInfoFromDatabase(in Bundle updateServiceInfo);
+ // Update all service information by the contents of serviceInfoList.
+ int updateServiceInfoByListFromDatabase(in Bundle[] updateServiceInfoList);
+ // Remove a service information of the serviceInfoId from the service list.
+ int removeServiceInfoFromDatabase(String serviceInfoId);
+ // Remove all service information of the serviceInfoId from the service list.
+ int removeServiceInfoByListFromDatabase(in String[] serviceInfoIdList);
+ // Get a list of the Service list IDs which is equivalent to COLUMN_CHANNEL_LIST_ID
+ // in Channels table from tv db.
+ String[] getServiceListChannelIds();
+ // Get the information associated with the Service list Channel id.
+ Bundle getServiceListInfoByChannelId(String serviceListChannelId, in String[] keys);
+
+ // Get a list of transportStream records' information specified by serviceListId and keys.
+ Bundle getTransportStreamInfoList(String serviceListId, in String[] keys);
+ // Get a list of transportStream records' information specified by serviceListId and keys
+ // from work db.
+ Bundle getTransportStreamInfoListForce(String serviceListId, in String[] keys);
+
+ // Get a list of network records' information specified by serviceListId and keys.
+ Bundle getNetworkInfoList(String serviceListId, in String[] keys);
+ // Get a list of satellite records' information specified by serviceListId and keys.
+ Bundle getSatelliteInfoList(String serviceListId, in String[] keys);
+
+ // Decompress whole bundle value of single service/transportStream/Network/Satellite record.
+ // RecordInfoBundle:a single record got from database by getServiceInfoFromDatabase()
+ String toRecordInfoByType(in Bundle recordInfoBundle, String recordType);
+ // Set channels(tv.db) modified result to middleware database(SVL/TSL/NWL/SATL).
+ int putRecordIdList(String serviceListId, in Bundle recordIdListBundle, int optType);
+
+ // Add predefined ServiceListInfo of Hotbird 13E in scan two satellite scene EU region
+ // following by commit().
+ String addPredefinedServiceListInfo(int broadcastType, String serviceListType,
+ String serviceListPrefix, String countryCode, int operatorId);
+ // Add predefined channels of Hotbird 13E in scan two satellite scene EU region.
+ int addPredefinedChannelList(String serviceListId, in Bundle[] predefinedListBundle);
+ // Add predefined satellite info of Hotbird 13E in scan two satellite scene EU region.
+ int addPredefinedSatInfo(String serviceListId, in Bundle predefinedSatInfoBundle);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListEditListener.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListEditListener.aidl
new file mode 100644
index 000000000000..e227eda47d4f
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListEditListener.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+/**
+ * @hide
+ */
+oneway interface IServiceListEditListener {
+ void onCompleted(int requestId, int result);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListExportListener.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListExportListener.aidl
new file mode 100644
index 000000000000..c57e8f97ed4c
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListExportListener.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+/**
+ * @hide
+ */
+oneway interface IServiceListExportListener {
+ void onExported(int exportResult);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListExportSession.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListExportSession.aidl
new file mode 100644
index 000000000000..fcde581548f6
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListExportSession.aidl
@@ -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 android.media.tv.extension.servicedb;
+
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * @hide
+ */
+interface IServiceListExportSession {
+ // Start export service list with reserved parameters.
+ int exportServiceList(in ParcelFileDescriptor pfd, in Bundle exportParams);
+ // Release export resources.
+ int release();
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListImportListener.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListImportListener.aidl
new file mode 100644
index 000000000000..abd8320df11d
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListImportListener.aidl
@@ -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.
+ */
+
+package android.media.tv.extension.servicedb;
+
+/**
+ * @hide
+ */
+interface IServiceListImportListener {
+ void onImported(int importResult);
+ void onPreloaded(int preloadResult);
+} \ No newline at end of file
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListImportSession.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListImportSession.aidl
new file mode 100644
index 000000000000..1f1ae010a444
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListImportSession.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * @hide
+ */
+interface IServiceListImportSession {
+ // Start import service list. Should call after preload and before release.
+ int importServiceList(in ParcelFileDescriptor pfd, in Bundle importParams);
+ // Preparing for import.
+ int preload(in ParcelFileDescriptor pfd);
+ // Release import resources.
+ int release();
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListListener.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListListener.aidl
new file mode 100644
index 000000000000..7c9c5c8a8048
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListListener.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+/**
+ * @hide
+ */
+oneway interface IServiceListSetChannelListListener {
+ void onCompleted(int setChannelListResult);
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListSession.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListSession.aidl
new file mode 100644
index 000000000000..b0527b3709b7
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListSetChannelListSession.aidl
@@ -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 android.media.tv.extension.servicedb;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface IServiceListSetChannelListSession {
+ // Set channelList with channelinfo bundles, serviceListInfo, and operation type.
+ int setChannelList(in Bundle[] channelsInfo, in Bundle ServiceListInfoBundle, int optType);
+ // Release set channellist resources.
+ int release();
+}
diff --git a/media/java/android/media/tv/extension/servicedb/IServiceListTransferInterface.aidl b/media/java/android/media/tv/extension/servicedb/IServiceListTransferInterface.aidl
new file mode 100644
index 000000000000..91fb15728b06
--- /dev/null
+++ b/media/java/android/media/tv/extension/servicedb/IServiceListTransferInterface.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.media.tv.extension.servicedb;
+
+import android.media.tv.extension.servicedb.IServiceListExportListener;
+import android.media.tv.extension.servicedb.IServiceListImportListener;
+import android.media.tv.extension.servicedb.IServiceListSetChannelListListener;
+import android.os.IBinder;
+
+/**
+ * @hide
+ */
+interface IServiceListTransferInterface {
+ IBinder createExportSession(in IServiceListExportListener listener);
+ IBinder createImportSession(in IServiceListImportListener listener);
+ IBinder createSetChannelListSession(in IServiceListSetChannelListListener listener);
+}
diff --git a/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfo.aidl b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfo.aidl
new file mode 100644
index 000000000000..a3725e4e25db
--- /dev/null
+++ b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfo.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.media.tv.extension.teletext;
+
+import android.media.tv.extension.teletext.IDataServiceSignalInfoListener;
+import android.os.Bundle;
+
+
+/**
+ * @hide
+ */
+interface IDataServiceSignalInfo {
+ // Get Teletext data service signal information.
+ Bundle getDataServiceSignalInfo(String sessionToken);
+ // Add a listener that receives notifications of teletext running information.
+ void addDataServiceSignalInfoListener(String clientToken,
+ IDataServiceSignalInfoListener listener);
+ // Remove a listener that receives notifications of Teletext running information.
+ void removeDataServiceSignalInfoListener(String clientToken,
+ IDataServiceSignalInfoListener listener);
+}
diff --git a/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfoListener.aidl b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfoListener.aidl
new file mode 100644
index 000000000000..0e99bf5cc955
--- /dev/null
+++ b/media/java/android/media/tv/extension/teletext/IDataServiceSignalInfoListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.teletext;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IDataServiceSignalInfoListener {
+ void onDataServiceSignalInfoChanged (String sessionToken, in Bundle changedSignalInfo);
+}
diff --git a/media/java/android/media/tv/extension/teletext/ITeletextPageSubCode.aidl b/media/java/android/media/tv/extension/teletext/ITeletextPageSubCode.aidl
new file mode 100644
index 000000000000..c96ffc02f438
--- /dev/null
+++ b/media/java/android/media/tv/extension/teletext/ITeletextPageSubCode.aidl
@@ -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 android.media.tv.extension.teletext;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+interface ITeletextPageSubCode {
+ // Get Teletext page number
+ Bundle getTeletextPageNumber(String sessionToken);
+ // Set Teletext page number.
+ void setTeleltextPageNumber(String sessionToken, int pageNumber);
+ // Get Teletext sub page number.
+ Bundle getTeletextPageSubCode(String sessionToken);
+ // Set Teletext sub page number.
+ void setTeletextPageSubCode(String sessionToken, int pageSubCode);
+ // Get Teletext TopInfo.
+ Bundle getTeletextHasTopInfo(String sessionToken);
+ // Get Teletext TopBlockList.
+ Bundle getTeletextTopBlockList(String sessionToken);
+ // Get Teletext TopGroupList.
+ Bundle getTeletextTopGroupList(String sessionToken, int indexGroup);
+ // Get Teletext TopPageList.
+ Bundle getTeletextTopPageList(String sessionToken, int indexPage);
+}
diff --git a/media/java/android/media/tv/extension/tune/IChannelTunedInterface.aidl b/media/java/android/media/tv/extension/tune/IChannelTunedInterface.aidl
new file mode 100644
index 000000000000..88e50844f998
--- /dev/null
+++ b/media/java/android/media/tv/extension/tune/IChannelTunedInterface.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.media.tv.extension.tune;
+
+import android.media.tv.extension.tune.IChannelTunedListener;
+
+/*
+* @hide
+*/
+interface IChannelTunedInterface {
+ void addChannelTunedListener(in IChannelTunedListener listener);
+ void removeChannelTunedListener(in IChannelTunedListener listener);
+}
diff --git a/media/java/android/media/tv/extension/tune/IChannelTunedListener.aidl b/media/java/android/media/tv/extension/tune/IChannelTunedListener.aidl
new file mode 100644
index 000000000000..46875463402d
--- /dev/null
+++ b/media/java/android/media/tv/extension/tune/IChannelTunedListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.tune;
+
+import android.os.Bundle;
+
+/*
+* @hide
+*/
+oneway interface IChannelTunedListener {
+ void onChannelTuned(String sessionToken, in Bundle channelTunedInfo);
+}
diff --git a/media/java/android/media/tv/extension/tune/IMuxTune.aidl b/media/java/android/media/tv/extension/tune/IMuxTune.aidl
new file mode 100644
index 000000000000..4e9dbdae6643
--- /dev/null
+++ b/media/java/android/media/tv/extension/tune/IMuxTune.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.media.tv.extension.tune;
+
+import android.media.tv.extension.tune.IMuxTuneSession;
+
+/**
+* @hide
+*/
+interface IMuxTune {
+ IMuxTuneSession createSession(int broadcastType, String clientToken);
+}
diff --git a/media/java/android/media/tv/extension/tune/IMuxTuneSession.aidl b/media/java/android/media/tv/extension/tune/IMuxTuneSession.aidl
new file mode 100644
index 000000000000..5ad72b48b50b
--- /dev/null
+++ b/media/java/android/media/tv/extension/tune/IMuxTuneSession.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.media.tv.extension.tune;
+
+import android.os.Bundle;
+
+/**
+* @hide
+*/
+interface IMuxTuneSession {
+ // Start mux tune with tune params.
+ void start(int broadcastType, int frequency, int brandwith, in Bundle muxTuneParams);
+ // Stop mux tune.
+ void stop();
+ // Release muxtune resources.
+ void release();
+ // Get the session token created by TIS to identify different sessions.
+ String getSessionToken();
+}
diff --git a/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java b/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java
index c9807e626429..58aa56babb64 100644
--- a/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java
+++ b/media/tests/projection/src/android/media/projection/FakeIMediaProjection.java
@@ -46,7 +46,7 @@ public final class FakeIMediaProjection extends IMediaProjection.Stub {
}
@Override
- public void stop() throws RemoteException {
+ public void stop(@StopReason int stopReason) throws RemoteException {
// Pass along to the client's callback wrapper.
mIMediaProjectionCallback.onStop();
}
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 7ae2eafaf461..0ee81cbb7a73 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -202,6 +202,7 @@ package android.nfc.cardemulation {
method public boolean categoryAllowsForegroundPreference(String);
method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService();
method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String);
+ method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public int getDefaultNfcSubscriptionId();
method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public CharSequence getDescriptionForPreferredPaymentService();
method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService();
@@ -232,6 +233,7 @@ package android.nfc.cardemulation {
field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1; // 0x1
field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2; // 0x2
field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0; // 0x0
+ field @FlaggedApi("android.nfc.nfc_associated_role_services") public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY = "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3; // 0x3
field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0; // 0x0
field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1; // 0x1
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 15814edcd86a..3ed9b7667be7 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -57,17 +57,19 @@ package android.nfc {
@FlaggedApi("android.nfc.nfc_oem_extension") public final class NfcOemExtension {
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int forceRoutingTableCommit();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.List<java.lang.String> getActiveNfceeList();
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getActiveNfceeList();
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public long getMaxPausePollingTimeoutMills();
method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.nfc.RoutingStatus getRoutingStatus();
method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.List<android.nfc.NfcRoutingTableEntry> getRoutingTable();
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.T4tNdefNfcee getT4tNdefNfcee();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean hasUserEnabledNfc();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAutoChangeEnabled();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagPresent();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void maybeTriggerFirmwareUpdate();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overwriteRoutingTable(int, int, int, int);
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void pausePolling(int);
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int pausePolling(long);
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback);
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void resumePolling();
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int resumePolling();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setAutoChangeEnabled(boolean);
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void setControllerAlwaysOnMode(int);
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void synchronizeScreenState();
@@ -83,6 +85,8 @@ package android.nfc {
field public static final int HCE_ACTIVATE = 1; // 0x1
field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2
field public static final int HCE_DEACTIVATE = 3; // 0x3
+ field public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2; // 0x2
+ field public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1; // 0x1
field public static final int STATUS_OK = 0; // 0x0
field public static final int STATUS_UNKNOWN_ERROR = 1; // 0x1
}
@@ -120,6 +124,11 @@ package android.nfc {
@FlaggedApi("android.nfc.nfc_oem_extension") public abstract class NfcRoutingTableEntry {
method public int getNfceeId();
+ method public int getType();
+ field public static final int TYPE_AID = 0; // 0x0
+ field public static final int TYPE_PROTOCOL = 1; // 0x1
+ field public static final int TYPE_SYSTEM_CODE = 3; // 0x3
+ field public static final int TYPE_TECHNOLOGY = 2; // 0x2
}
@FlaggedApi("android.nfc.nfc_oem_extension") public final class OemLogItems implements android.os.Parcelable {
@@ -179,6 +188,47 @@ package android.nfc {
field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_V = 3; // 0x3
}
+ @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfcee {
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int clearData();
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isOperationOngoing();
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isSupported();
+ method @Nullable @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public android.nfc.T4tNdefNfceeCcFileInfo readCcfile();
+ method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public byte[] readData(@IntRange(from=0, to=65535) int);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int writeData(@IntRange(from=0, to=65535) int, @NonNull byte[]);
+ field public static final int CLEAR_DATA_FAILED_INTERNAL = 0; // 0x0
+ field public static final int CLEAR_DATA_SUCCESS = 1; // 0x1
+ field public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6; // 0xfffffffa
+ field public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7; // 0xfffffff9
+ field public static final int WRITE_DATA_ERROR_INTERNAL = -1; // 0xffffffff
+ field public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4; // 0xfffffffc
+ field public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5; // 0xfffffffb
+ field public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8; // 0xfffffff8
+ field public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3; // 0xfffffffd
+ field public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2; // 0xfffffffe
+ field public static final int WRITE_DATA_SUCCESS = 0; // 0x0
+ }
+
+ @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfceeCcFileInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method @IntRange(from=15, to=32767) public int getCcFileLength();
+ method @IntRange(from=0xffffffff, to=65535) public int getFileId();
+ method @IntRange(from=15, to=65535) public int getMaxReadLength();
+ method @IntRange(from=5, to=32767) public int getMaxSize();
+ method @IntRange(from=13, to=65535) public int getMaxWriteLength();
+ method public int getReadAccess();
+ method public int getVersion();
+ method public int getWriteAccess();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.nfc.T4tNdefNfceeCcFileInfo> CREATOR;
+ field public static final int READ_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
+ field public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
+ field public static final int VERSION_2_0 = 32; // 0x20
+ field public static final int VERSION_3_0 = 48; // 0x30
+ field public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
+ field public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
+ field public static final int WRITE_ACCESS_NOT_GRANTED = 255; // 0xff
+ }
+
}
package android.nfc.cardemulation {
@@ -186,14 +236,19 @@ package android.nfc.cardemulation {
public final class CardEmulation {
method @FlaggedApi("android.permission.flags.wallet_role_enabled") @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static android.content.ComponentName getPreferredPaymentService(@NonNull android.content.Context);
method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int);
- method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void overrideRoutingTable(@NonNull android.app.Activity, int, int);
- method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void recoverRoutingTable(@NonNull android.app.Activity);
+ method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overrideRoutingTable(@NonNull android.app.Activity, int, int);
+ method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void recoverRoutingTable(@NonNull android.app.Activity);
+ method @FlaggedApi("android.nfc.enable_card_emulation_euicc") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setDefaultNfcSubscriptionId(int);
method @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setServiceEnabledForCategoryOther(@NonNull android.content.ComponentName, boolean);
field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3; // 0x3
field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1; // 0x1
field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2; // 0x2
field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4; // 0x4
field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_OK = 0; // 0x0
+ field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2; // 0x2
+ field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1; // 0x1
+ field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3; // 0x3
+ field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0; // 0x0
}
}
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index a08b55fe86b8..ac0a5aaaa195 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -31,6 +31,7 @@ import android.nfc.INfcCardEmulation;
import android.nfc.INfcFCardEmulation;
import android.nfc.INfcOemExtensionCallback;
import android.nfc.INfcUnlockHandler;
+import android.nfc.IT4tNdefNfcee;
import android.nfc.ITagRemovedCallback;
import android.nfc.INfcDta;
import android.nfc.INfcWlcStateListener;
@@ -52,8 +53,8 @@ interface INfcAdapter
int getState();
boolean disable(boolean saveState, in String pkg);
boolean enable(in String pkg);
- void pausePolling(int timeoutInMs);
- void resumePolling();
+ int pausePolling(long timeoutInMs);
+ int resumePolling();
void setForegroundDispatch(in PendingIntent intent,
in IntentFilter[] filters, in TechListParcel techLists);
@@ -114,7 +115,7 @@ interface INfcAdapter
void clearPreference();
void setScreenState();
void checkFirmware();
- List<String> fetchActiveNfceeList();
+ Map fetchActiveNfceeList();
void triggerInitialization();
boolean getSettingStatus();
boolean isTagPresent();
@@ -122,4 +123,6 @@ interface INfcAdapter
void indicateDataMigration(boolean inProgress, String pkg);
int commitRouting();
boolean isTagIntentAllowed(in String pkg, in int Userid);
+ IT4tNdefNfcee getT4tNdefNfceeInterface();
+ long getMaxPausePollingTimeoutMs();
}
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
index 633d8bfbbb67..bb9fe959dc06 100644
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ b/nfc/java/android/nfc/INfcCardEmulation.aidl
@@ -53,6 +53,8 @@ interface INfcCardEmulation
void overrideRoutingTable(int userHandle, String protocol, String technology, in String pkg);
void recoverRoutingTable(int userHandle);
boolean isEuiccSupported();
+ int getDefaultNfcSubscriptionId(in String pkg);
+ int setDefaultNfcSubscriptionId(int subscriptionId, in String pkg);
void setAutoChangeStatus(boolean state);
boolean isAutoChangeEnabled();
List<String> getRoutingStatus();
diff --git a/nfc/java/android/nfc/IT4tNdefNfcee.aidl b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
new file mode 100644
index 000000000000..b4cda5b022fb
--- /dev/null
+++ b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2024 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+package android.nfc;
+
+import android.nfc.T4tNdefNfceeCcFileInfo;
+
+/**
+ * @hide
+ */
+interface IT4tNdefNfcee {
+ int writeData(in int fileId, in byte[] data);
+ byte[] readData(in int fileId);
+ int clearNdefData();
+ boolean isNdefOperationOngoing();
+ boolean isNdefNfceeEmulationSupported();
+ T4tNdefNfceeCcFileInfo readCcfile();
+}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 056844f38f3c..89ce4239cd4d 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -589,6 +589,7 @@ public final class NfcAdapter {
static INfcTag sTagService;
static INfcCardEmulation sCardEmulationService;
static INfcFCardEmulation sNfcFCardEmulationService;
+ static IT4tNdefNfcee sNdefNfceeService;
/**
* The NfcAdapter object for each application context.
@@ -827,7 +828,13 @@ public final class NfcAdapter {
throw new UnsupportedOperationException();
}
}
-
+ try {
+ sNdefNfceeService = sService.getT4tNdefNfceeInterface();
+ } catch (RemoteException e) {
+ sNdefNfceeService = null;
+ Log.e(TAG, "could not retrieve NDEF NFCEE service");
+ throw new UnsupportedOperationException();
+ }
sIsInitialized = true;
}
NfcAdapter adapter = sNfcAdapters.get(context);
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index 9ed678fe6014..f78161e7cad0 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -39,6 +39,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ResultReceiver;
+import android.se.omapi.Reader;
import android.util.Log;
import java.lang.annotation.Retention;
@@ -148,6 +149,48 @@ public final class NfcOemExtension {
public @interface ControllerMode{}
/**
+ * Technology Type for {@link #getActiveNfceeList()}.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int NFCEE_TECH_NONE = 0;
+
+ /**
+ * Technology Type for {@link #getActiveNfceeList()}.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int NFCEE_TECH_A = 1;
+
+ /**
+ * Technology Type for {@link #getActiveNfceeList()}.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int NFCEE_TECH_B = 1 << 1;
+
+ /**
+ * Technology Type for {@link #getActiveNfceeList()}.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public static final int NFCEE_TECH_F = 1 << 2;
+
+ /**
+ * Nfc technology flags for {@link #getActiveNfceeList()}.
+ *
+ * @hide
+ */
+ @IntDef(flag = true, value = {
+ NFCEE_TECH_NONE,
+ NFCEE_TECH_A,
+ NFCEE_TECH_B,
+ NFCEE_TECH_F,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface NfceeTechnology {}
+
+ /**
* Event that Host Card Emulation is activated.
*/
public static final int HCE_ACTIVATE = 1;
@@ -173,6 +216,31 @@ public final class NfcOemExtension {
public @interface HostCardEmulationAction {}
/**
+ * Status code returned when the polling state change request succeeded.
+ * @see #pausePolling()
+ * @see #resumePolling()
+ */
+ public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1;
+ /**
+ * Status code returned when the polling state change request is already in
+ * required state.
+ * @see #pausePolling()
+ * @see #resumePolling()
+ */
+ public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2;
+ /**
+ * Possible status codes for {@link #pausePolling()} and
+ * {@link #resumePolling()}.
+ * @hide
+ */
+ @IntDef(value = {
+ POLLING_STATE_CHANGE_SUCCEEDED,
+ POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PollingStateChangeStatusCode {}
+
+ /**
* Status OK
*/
public static final int STATUS_OK = 0;
@@ -467,6 +535,28 @@ public final class NfcOemExtension {
}
/**
+ * Get an instance of {@link T4tNdefNfcee} object for performing T4T (Type-4 Tag)
+ * NDEF (NFC Data Exchange Format) NFCEE (NFC Execution Environment) operations.
+ * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
+ * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
+ * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ *
+ * This is a singleton object which shall be used by OEM extension module to do NDEF-NFCEE
+ * read/write operations.
+ *
+ * <p>Returns {@link T4tNdefNfcee}
+ * <p>Does not cause any RF activity and does not block.
+ * @return NFC Data Exchange Format (NDEF) NFC Execution Environment (NFCEE) object
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public T4tNdefNfcee getT4tNdefNfcee() {
+ return T4tNdefNfcee.getInstance();
+ }
+
+ /**
* Register an {@link Callback} to listen for NFC oem extension callbacks
* Multiple clients can register and callbacks will be invoked asynchronously.
*
@@ -580,14 +670,18 @@ public final class NfcOemExtension {
/**
* Get the Active NFCEE (NFC Execution Environment) List
*
- * @return List of activated secure elements on success
- * which can contain "eSE" and "UICC", otherwise empty list.
+ * @see Reader#getName() for the list of possible NFCEE names.
+ *
+ * @return Map< String, @NfceeTechnology Integer >
+ * A HashMap where keys are activated secure elements and
+ * the values are bitmap of technologies supported by each secure element
+ * on success keys can contain "eSE" and "UICC", otherwise empty map.
*/
@NonNull
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public List<String> getActiveNfceeList() {
+ public Map<String, Integer> getActiveNfceeList() {
return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sService.fetchActiveNfceeList(), new ArrayList<String>());
+ NfcAdapter.sService.fetchActiveNfceeList(), new HashMap<String, Integer>());
}
/**
@@ -653,24 +747,45 @@ public final class NfcOemExtension {
/**
* Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
- * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely
- * use {@link #resumePolling()} to resume the polling.
- * @param timeoutInMs the pause polling duration in millisecond, ranging from 0 to 40000.
+ * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely.
+ * Use {@link #resumePolling()} to resume the polling.
+ * Use {@link #getMaxPausePollingTimeoutMs()} to check the max timeout value.
+ * @param timeoutInMs the pause polling duration in millisecond.
+ * @return status of the operation
+ * @throws IllegalArgumentException if timeoutInMs value is invalid
+ * (0 < timeoutInMs < max).
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void pausePolling(@DurationMillisLong int timeoutInMs) {
- NfcAdapter.callService(() -> NfcAdapter.sService.pausePolling(timeoutInMs));
+ public @PollingStateChangeStatusCode int pausePolling(@DurationMillisLong long timeoutInMs) {
+ return NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sService.pausePolling(timeoutInMs),
+ POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
}
/**
* Resumes default NFC tag reader mode polling for the current device state if polling is
* paused. Calling this while already in polling is a no-op.
+ * @return status of the operation
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public @PollingStateChangeStatusCode int resumePolling() {
+ return NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sService.resumePolling(),
+ POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
+ }
+
+ /**
+ * Gets the max pause polling timeout value in millisecond.
+ * @return long integer representing the max timeout
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void resumePolling() {
- NfcAdapter.callService(() -> NfcAdapter.sService.resumePolling());
+ @DurationMillisLong
+ public long getMaxPausePollingTimeoutMills() {
+ return NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sService.getMaxPausePollingTimeoutMs(), 0L);
}
/**
diff --git a/nfc/java/android/nfc/NfcRoutingTableEntry.java b/nfc/java/android/nfc/NfcRoutingTableEntry.java
index 4e913776a030..c2cbbede9b75 100644
--- a/nfc/java/android/nfc/NfcRoutingTableEntry.java
+++ b/nfc/java/android/nfc/NfcRoutingTableEntry.java
@@ -17,8 +17,12 @@ package android.nfc;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.SystemApi;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Class to represent an entry of routing table. This class is abstract and extended by
* {@link RoutingTableTechnologyEntry}, {@link RoutingTableProtocolEntry},
@@ -30,10 +34,42 @@ import android.annotation.SystemApi;
@SystemApi
public abstract class NfcRoutingTableEntry {
private final int mNfceeId;
+ private final int mType;
+
+ /**
+ * AID routing table type.
+ */
+ public static final int TYPE_AID = 0;
+ /**
+ * Protocol routing table type.
+ */
+ public static final int TYPE_PROTOCOL = 1;
+ /**
+ * Technology routing table type.
+ */
+ public static final int TYPE_TECHNOLOGY = 2;
+ /**
+ * System Code routing table type.
+ */
+ public static final int TYPE_SYSTEM_CODE = 3;
+
+ /**
+ * Possible type of this routing table entry.
+ * @hide
+ */
+ @IntDef(prefix = "TYPE_", value = {
+ TYPE_AID,
+ TYPE_PROTOCOL,
+ TYPE_TECHNOLOGY,
+ TYPE_SYSTEM_CODE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RoutingTableType {}
/** @hide */
- protected NfcRoutingTableEntry(int nfceeId) {
+ protected NfcRoutingTableEntry(int nfceeId, @RoutingTableType int type) {
mNfceeId = nfceeId;
+ mType = type;
}
/**
@@ -43,4 +79,13 @@ public abstract class NfcRoutingTableEntry {
public int getNfceeId() {
return mNfceeId;
}
+
+ /**
+ * Get the type of this entry.
+ * @return an integer defined in {@link RoutingTableType}
+ */
+ @RoutingTableType
+ public int getType() {
+ return mType;
+ }
}
diff --git a/nfc/java/android/nfc/RoutingTableAidEntry.java b/nfc/java/android/nfc/RoutingTableAidEntry.java
index 7634fe342ab9..bf697d662bd6 100644
--- a/nfc/java/android/nfc/RoutingTableAidEntry.java
+++ b/nfc/java/android/nfc/RoutingTableAidEntry.java
@@ -20,7 +20,7 @@ import android.annotation.NonNull;
import android.annotation.SystemApi;
/**
- * Represents an AID entry in current routing table.
+ * Represents an Application ID (AID) entry in current routing table.
* @hide
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@@ -30,7 +30,7 @@ public class RoutingTableAidEntry extends NfcRoutingTableEntry {
/** @hide */
public RoutingTableAidEntry(int nfceeId, String value) {
- super(nfceeId);
+ super(nfceeId, TYPE_AID);
this.mValue = value;
}
diff --git a/nfc/java/android/nfc/RoutingTableProtocolEntry.java b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
index 0c5be7dd9d97..536de4d7430e 100644
--- a/nfc/java/android/nfc/RoutingTableProtocolEntry.java
+++ b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
@@ -97,7 +97,7 @@ public class RoutingTableProtocolEntry extends NfcRoutingTableEntry {
/** @hide */
public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value) {
- super(nfceeId);
+ super(nfceeId, TYPE_PROTOCOL);
this.mValue = value;
}
diff --git a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
index f87ad5f95195..f61892d31668 100644
--- a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
+++ b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
@@ -20,7 +20,9 @@ import android.annotation.NonNull;
import android.annotation.SystemApi;
/**
- * Represents a system code entry in current routing table.
+ * Represents a system code entry in current routing table, where system codes are two-byte values
+ * used in NFC-F technology (a type of NFC communication) to identify specific
+ * device configurations.
* @hide
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@@ -30,7 +32,7 @@ public class RoutingTableSystemCodeEntry extends NfcRoutingTableEntry {
/** @hide */
public RoutingTableSystemCodeEntry(int nfceeId, byte[] value) {
- super(nfceeId);
+ super(nfceeId, TYPE_SYSTEM_CODE);
this.mValue = value;
}
diff --git a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
index f51a5299be11..2dbc94232b0b 100644
--- a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
+++ b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
@@ -30,22 +30,27 @@ import java.lang.annotation.RetentionPolicy;
@SystemApi
public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry {
/**
- * Technology-A
+ * Technology-A.
+ * <p>Tech-A is mostly used for payment and ticketing applications. It supports various
+ * Tag platforms including Type 1, Type 2 and Type 4A tags. </p>
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int TECHNOLOGY_A = 0;
/**
- * Technology-B
+ * Technology-B which is based on ISO/IEC 14443-3 standard.
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int TECHNOLOGY_B = 1;
/**
- * Technology-F
+ * Technology-F.
+ * <p>Tech-F is a standard which supports Type 3 Tags and NFC-DEP protocol etc.</p>
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int TECHNOLOGY_F = 2;
/**
- * Technology-V
+ * Technology-V.
+ * <p>Tech-V is an NFC technology used for communication with passive tags that operate
+ * at a longer range than other NFC technologies. </p>
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
public static final int TECHNOLOGY_V = 3;
@@ -73,7 +78,7 @@ public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry {
/** @hide */
public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value) {
- super(nfceeId);
+ super(nfceeId, TYPE_TECHNOLOGY);
this.mValue = value;
}
diff --git a/nfc/java/android/nfc/T4tNdefNfcee.java b/nfc/java/android/nfc/T4tNdefNfcee.java
new file mode 100644
index 000000000000..06d02c54eb2e
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfcee.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.WorkerThread;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class is used for performing T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
+ * NFCEE (NFC Execution Environment) operations.
+ * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
+ * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
+ * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class T4tNdefNfcee {
+ private static final String TAG = "NdefNfcee";
+ static T4tNdefNfcee sNdefNfcee;
+
+ private T4tNdefNfcee() {
+ }
+
+ /**
+ * Helper to get an instance of this class.
+ *
+ * @return
+ * @hide
+ */
+ @NonNull
+ public static T4tNdefNfcee getInstance() {
+ if (sNdefNfcee == null) {
+ sNdefNfcee = new T4tNdefNfcee();
+ }
+ return sNdefNfcee;
+ }
+
+ /**
+ * Return flag for {@link #writeData(int, byte[])}.
+ * It indicates write data is successful.
+ */
+ public static final int WRITE_DATA_SUCCESS = 0;
+ /**
+ * Return flag for {@link #writeData(int, byte[])}.
+ * It indicates write data fail due to unknown reasons.
+ */
+ public static final int WRITE_DATA_ERROR_INTERNAL = -1;
+ /**
+ * Return flag for {@link #writeData(int, byte[])}.
+ * It indicates write data fail due to ongoing rf activity.
+ */
+ public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2;
+ /**
+ * Return flag for {@link #writeData(int, byte[])}.
+ * It indicates write data fail due to Nfc off.
+ */
+ public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3;
+ /**
+ * Return flag for {@link #writeData(int, byte[])}.
+ * It indicates write data fail due to invalid file id.
+ */
+ public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4;
+ /**
+ * Return flag for {@link #writeData(int, byte[])}.
+ * It indicates write data fail due to invalid length.
+ */
+ public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5;
+ /**
+ * Return flag for {@link #writeData(int, byte[])}.
+ * It indicates write data fail due to core connection create failure.
+ */
+ public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6;
+ /**
+ * Return flag for {@link #writeData(int, byte[])}.
+ * It indicates write data fail due to empty payload.
+ */
+ public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7;
+ /**
+ * Returns flag for {@link #writeData(int, byte[])}.
+ * It idicates write data fail due to invalid ndef format.
+ */
+ public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8;
+
+ /**
+ * Possible return values for {@link #writeData(int, byte[])}.
+ *
+ * @hide
+ */
+ @IntDef(prefix = { "WRITE_DATA_" }, value = {
+ WRITE_DATA_SUCCESS,
+ WRITE_DATA_ERROR_INTERNAL,
+ WRITE_DATA_ERROR_RF_ACTIVATED,
+ WRITE_DATA_ERROR_NFC_NOT_ON,
+ WRITE_DATA_ERROR_INVALID_FILE_ID,
+ WRITE_DATA_ERROR_INVALID_LENGTH,
+ WRITE_DATA_ERROR_CONNECTION_FAILED,
+ WRITE_DATA_ERROR_EMPTY_PAYLOAD,
+ WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface WriteDataStatus{}
+
+ /**
+ * This API performs writes of T4T data to NFCEE.
+ *
+ * <p>This is an I/O operation and will block until complete. It must
+ * not be called from the main application thread.</p>
+ *
+ * @param fileId File id (Refer NFC Forum Type 4 Tag Specification
+ * Section 4.2 File Identifiers and Access Conditions
+ * for more information) to which to write.
+ * @param data This should be valid Ndef Message format.
+ * Refer to Nfc forum NDEF specification NDEF Message section
+ * @return status of the operation.
+ * @hide
+ */
+ @SystemApi
+ @WorkerThread
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public @WriteDataStatus int writeData(@IntRange(from = 0, to = 65535) int fileId,
+ @NonNull byte[] data) {
+ return NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sNdefNfceeService.writeData(fileId, data), WRITE_DATA_ERROR_INTERNAL);
+ }
+
+ /**
+ * This API performs reading of T4T content of Nfcee.
+ *
+ * <p>This is an I/O operation and will block until complete. It must
+ * not be called from the main application thread.</p>
+ *
+ * @param fileId File Id (Refer
+ * Section 4.2 File Identifiers and Access Conditions
+ * for more information) from which to read.
+ * @return - Returns Ndef message if success
+ * Refer to Nfc forum NDEF specification NDEF Message section
+ * @throws IllegalStateException if read fails because the fileId is invalid.
+ * @hide
+ */
+ @SystemApi
+ @WorkerThread
+ @NonNull
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public byte[] readData(@IntRange(from = 0, to = 65535) int fileId) {
+ return NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sNdefNfceeService.readData(fileId), null);
+ }
+
+ /**
+ * Return flag for {@link #clearNdefData()}.
+ * It indicates clear data is successful.
+ */
+ public static final int CLEAR_DATA_SUCCESS = 1;
+ /**
+ * Return flag for {@link #clearNdefData()}.
+ * It indicates clear data failed due to internal error while processing the clear.
+ */
+ public static final int CLEAR_DATA_FAILED_INTERNAL = 0;
+
+ /**
+ * Possible return values for {@link #clearNdefData()}.
+ *
+ * @hide
+ */
+ @IntDef(prefix = { "CLEAR_DATA_" }, value = {
+ CLEAR_DATA_SUCCESS,
+ CLEAR_DATA_FAILED_INTERNAL,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ClearDataStatus{}
+
+ /**
+ * This API will set all the T4T NDEF NFCEE data to zero.
+ *
+ * <p>This is an I/O operation and will block until complete. It must
+ * not be called from the main application thread.
+ *
+ * <p>This API can be called regardless of NDEF file lock state.
+ * </p>
+ * @return status of the operation
+ *
+ * @hide
+ */
+ @SystemApi
+ @WorkerThread
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public @ClearDataStatus int clearData() {
+ return NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sNdefNfceeService.clearNdefData(), CLEAR_DATA_FAILED_INTERNAL);
+ }
+
+ /**
+ * Returns whether NDEF NFCEE operation is ongoing or not.
+ *
+ * @return true if NDEF NFCEE operation is ongoing, else false.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public boolean isOperationOngoing() {
+ return NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sNdefNfceeService.isNdefOperationOngoing(), false);
+ }
+
+ /**
+ * This Api is to check the status of NDEF NFCEE emulation feature is
+ * supported or not.
+ *
+ * @return true if NDEF NFCEE emulation feature is supported, else false.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ public boolean isSupported() {
+ return NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sNdefNfceeService.isNdefNfceeEmulationSupported(), false);
+ }
+
+ /**
+ * This API performs reading of T4T NDEF NFCEE CC file content.
+ *
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+ *
+ * @return Returns CC file content if success or null if failed to read.
+ * @hide
+ */
+ @SystemApi
+ @WorkerThread
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ @Nullable
+ public T4tNdefNfceeCcFileInfo readCcfile() {
+ return NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sNdefNfceeService.readCcfile(), null);
+ }
+}
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
new file mode 100644
index 000000000000..f72f74e8b3b9
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+parcelable T4tNdefNfceeCcFileInfo;
+
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
new file mode 100644
index 000000000000..5fca0529124e
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class is used to represence T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
+ * NFCEE (NFC Execution Environment) CC (Capability Container) File data.
+ * The CC file stores metadata about the T4T tag being emulated.
+ *
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class T4tNdefNfceeCcFileInfo implements Parcelable {
+ /**
+ * Indicates the size of this capability container (called “CC File”)<p>
+ */
+ private int mCcLength;
+ /**
+ * Indicates the mapping specification version<p>
+ */
+ private int mVersion;
+ /**
+ * Indicates the max data size by a single ReadBinary<p>
+ */
+ private int mMaxReadLength;
+ /**
+ * Indicates the max data size by a single UpdateBinary<p>
+ */
+ private int mMaxWriteLength;
+ /**
+ * Indicates the NDEF File Identifier<p>
+ */
+ private int mFileId;
+ /**
+ * Indicates the maximum Max NDEF file size<p>
+ */
+ private int mMaxSize;
+ /**
+ * Indicates the read access condition<p>
+ */
+ private int mReadAccess;
+ /**
+ * Indicates the write access condition<p>
+ */
+ private int mWriteAccess;
+
+ /**
+ * Constructor to be used by NFC service and internal classes.
+ * @hide
+ */
+ public T4tNdefNfceeCcFileInfo(int cclen, int version, int maxLe, int maxLc,
+ int ndefFileId, int ndefMaxSize,
+ int ndefReadAccess, int ndefWriteAccess) {
+ mCcLength = cclen;
+ mVersion = version;
+ mMaxWriteLength = maxLc;
+ mMaxReadLength = maxLe;
+ mFileId = ndefFileId;
+ mMaxSize = ndefMaxSize;
+ mReadAccess = ndefReadAccess;
+ mWriteAccess = ndefWriteAccess;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+
+ dest.writeInt(mCcLength);
+ dest.writeInt(mVersion);
+ dest.writeInt(mMaxWriteLength);
+ dest.writeInt(mMaxReadLength);
+ dest.writeInt(mFileId);
+ dest.writeInt(mMaxSize);
+ dest.writeInt(mReadAccess);
+ dest.writeInt(mWriteAccess);
+ }
+
+ /**
+ * Indicates the size of this capability container (called “CC File”).
+ *
+ * @return length of the CC file.
+ */
+ @IntRange(from = 0xf, to = 0x7fff)
+ public int getCcFileLength() {
+ return mCcLength;
+ }
+
+ /**
+ * T4T tag mapping version 2.0.
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+ */
+ public static final int VERSION_2_0 = 0x20;
+ /**
+ * T4T tag mapping version 2.0.
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+ */
+ public static final int VERSION_3_0 = 0x30;
+
+ /**
+ * Possible return values for {@link #getVersion()}.
+ * @hide
+ */
+ @IntDef(prefix = { "VERSION_" }, value = {
+ VERSION_2_0,
+ VERSION_3_0,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Version{}
+
+ /**
+ * Indicates the mapping version of the T4T tag supported.
+ *
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.5" for more details.
+ *
+ * @return version of the specification
+ */
+ @Version
+ public int getVersion() {
+ return mVersion;
+ }
+
+ /**
+ * Indicates the max data size that can be read by a single invocation of
+ * {@link T4tNdefNfcee#readData(int)}.
+ *
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLe.
+ * @return max size of read (in bytes).
+ */
+ @IntRange(from = 0xf, to = 0xffff)
+ public int getMaxReadLength() {
+ return mMaxReadLength;
+ }
+
+ /**
+ * Indicates the max data size that can be written by a single invocation of
+ * {@link T4tNdefNfcee#writeData(int, byte[])}
+ *
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLc.
+ * @return max size of write (in bytes).
+ */
+ @IntRange(from = 0xd, to = 0xffff)
+ public int getMaxWriteLength() {
+ return mMaxWriteLength;
+ }
+
+ /**
+ * Indicates the NDEF File Identifier. This is the identifier used in the last invocation of
+ * {@link T4tNdefNfcee#writeData(int, byte[])}
+ *
+ * @return FileId of the data stored or -1 if no data is present.
+ */
+ @IntRange(from = -1, to = 65535)
+ public int getFileId() {
+ return mFileId;
+ }
+
+ /**
+ * Indicates the maximum size of T4T NDEF data that can be written to the NFCEE.
+ *
+ * @return max size of the contents.
+ */
+ @IntRange(from = 0x5, to = 0x7fff)
+ public int getMaxSize() {
+ return mMaxSize;
+ }
+
+ /**
+ * T4T tag read access granted without any security.
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ */
+ public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0x0;
+ /**
+ * T4T tag read access granted with limited proprietary access only.
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ */
+ public static final int READ_ACCESS_GRANTED_RESTRICTED = 0x80;
+
+ /**
+ * Possible return values for {@link #getVersion()}.
+ * @hide
+ */
+ @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
+ READ_ACCESS_GRANTED_RESTRICTED,
+ READ_ACCESS_GRANTED_UNRESTRICTED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ReadAccess {}
+
+ /**
+ * Indicates the read access condition.
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ * @return read access restriction
+ */
+ @ReadAccess
+ public int getReadAccess() {
+ return mReadAccess;
+ }
+
+ /**
+ * T4T tag write access granted without any security.
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ */
+ public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0x0;
+ /**
+ * T4T tag write access granted with limited proprietary access only.
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ */
+ public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 0x80;
+ /**
+ * T4T tag write access not granted.
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ */
+ public static final int WRITE_ACCESS_NOT_GRANTED = 0xFF;
+
+ /**
+ * Possible return values for {@link #getVersion()}.
+ * @hide
+ */
+ @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
+ WRITE_ACCESS_GRANTED_RESTRICTED,
+ WRITE_ACCESS_GRANTED_UNRESTRICTED,
+ WRITE_ACCESS_NOT_GRANTED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface WriteAccess {}
+
+ /**
+ * Indicates the write access condition.
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ * @return write access restriction
+ */
+ @WriteAccess
+ public int getWriteAccess() {
+ return mWriteAccess;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final @NonNull Parcelable.Creator<T4tNdefNfceeCcFileInfo> CREATOR =
+ new Parcelable.Creator<>() {
+ @Override
+ public T4tNdefNfceeCcFileInfo createFromParcel(Parcel in) {
+
+ // NdefNfceeCcFileInfo fields
+ int cclen = in.readInt();
+ int version = in.readInt();
+ int maxLe = in.readInt();
+ int maxLc = in.readInt();
+ int ndefFileId = in.readInt();
+ int ndefMaxSize = in.readInt();
+ int ndefReadAccess = in.readInt();
+ int ndefWriteAccess = in.readInt();
+
+ return new T4tNdefNfceeCcFileInfo(cclen, version, maxLe, maxLc,
+ ndefFileId, ndefMaxSize,
+ ndefReadAccess, ndefWriteAccess);
+ }
+
+ @Override
+ public T4tNdefNfceeCcFileInfo[] newArray(int size) {
+ return new T4tNdefNfceeCcFileInfo[size];
+ }
+ };
+}
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
index 9ff83fe77c9b..308b5d1831a6 100644
--- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -171,6 +171,12 @@ public final class ApduServiceInfo implements Parcelable {
private boolean mShouldDefaultToObserveMode;
/**
+ * Whether or not this service wants to share the same routing priority as the
+ * Wallet role owner.
+ */
+ private boolean mShareRolePriority;
+
+ /**
* @hide
*/
@UnsupportedAppUsage
@@ -307,6 +313,12 @@ public final class ApduServiceInfo implements Parcelable {
mShouldDefaultToObserveMode = sa.getBoolean(
R.styleable.HostApduService_shouldDefaultToObserveMode,
false);
+ if (Flags.nfcAssociatedRoleServices()) {
+ mShareRolePriority = sa.getBoolean(
+ R.styleable.HostApduService_shareRolePriority,
+ false
+ );
+ }
sa.recycle();
} else {
TypedArray sa = res.obtainAttributes(attrs,
@@ -337,6 +349,12 @@ public final class ApduServiceInfo implements Parcelable {
}
}
mStaticOffHostName = mOffHostName;
+ if (Flags.nfcAssociatedRoleServices()) {
+ mShareRolePriority = sa.getBoolean(
+ R.styleable.OffHostApduService_shareRolePriority,
+ false
+ );
+ }
sa.recycle();
}
@@ -728,6 +746,17 @@ public final class ApduServiceInfo implements Parcelable {
}
/**
+ * Returns whether or not this service wants to share the Wallet role holder priority
+ * with other packages/services with the same signature.
+ *
+ * @return whether or not this service wants to share priority
+ */
+ @FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES)
+ public boolean shareRolePriority() {
+ return mShareRolePriority;
+ }
+
+ /**
* Returns description of service.
* @return user readable description of service
*/
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index 24ff7ab9c2b6..803770218299 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -22,6 +22,7 @@ import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -45,6 +46,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
+import android.telephony.SubscriptionManager;
import android.util.ArrayMap;
import android.util.Log;
@@ -244,6 +246,25 @@ public final class CardEmulation {
@Retention(RetentionPolicy.SOURCE)
public @interface SetServiceEnabledStatusCode {}
+ /**
+ * Property name used to indicate that an application wants to allow associated services
+ * to share the same AID routing priority when this application is the role holder.
+ * <p>
+ * Example:
+ * <pre>
+ * {@code
+ * <application>
+ * ...
+ * <property android:name="android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY"
+ * android:value="true"/>
+ * </application>
+ * }
+ * </pre>
+ */
+ @FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES)
+ public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY =
+ "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
+
static boolean sIsInitialized = false;
static HashMap<Context, CardEmulation> sCardEmus = new HashMap<Context, CardEmulation>();
static INfcCardEmulation sService;
@@ -1010,6 +1031,7 @@ public final class CardEmulation {
* @hide
*/
@SystemApi
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
public void overrideRoutingTable(
@NonNull Activity activity, @ProtocolAndTechnologyRoute int protocol,
@@ -1037,6 +1059,7 @@ public final class CardEmulation {
* @hide
*/
@SystemApi
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
public void recoverRoutingTable(@NonNull Activity activity) {
if (!activity.isResumed()) {
@@ -1058,6 +1081,97 @@ public final class CardEmulation {
}
/**
+ * Setting the default subscription ID succeeded.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+ public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0;
+
+ /**
+ * Setting the default subscription ID failed because the subscription ID is invalid.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+ public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1;
+
+ /**
+ * Setting the default subscription ID failed because there was an internal error processing
+ * the request. For ex: NFC service died in the middle of handling the API.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+ public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2;
+
+ /**
+ * Setting the default subscription ID failed because this feature is not supported on the
+ * device.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+ public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3;
+
+ /** @hide */
+ @IntDef(prefix = "SET_SUBSCRIPTION_ID_STATUS_",
+ value = {
+ SET_SUBSCRIPTION_ID_STATUS_SUCCESS,
+ SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID,
+ SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR,
+ SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SetSubscriptionIdStatus {}
+
+ /**
+ * Sets the system's default NFC subscription id.
+ *
+ * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this sets the
+ * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+ *
+ * @param subscriptionId the default NFC subscription Id to set.
+ * @return status of the operation.
+ *
+ * @throws UnsupportedOperationException If the device does not have
+ * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
+ * @hide
+ */
+ @SystemApi
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+ public @SetSubscriptionIdStatus int setDefaultNfcSubscriptionId(int subscriptionId) {
+ return callServiceReturn(() ->
+ sService.setDefaultNfcSubscriptionId(
+ subscriptionId, mContext.getPackageName()),
+ SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR);
+ }
+
+ /**
+ * Returns the system's default NFC subscription id.
+ *
+ * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this returns the
+ * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+ * <p> If the device has no UICC that can serve as NFCEE, this will return
+ * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.</p>
+ *
+ * @return the default NFC subscription Id if set,
+ * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} otherwise.
+ *
+ * @throws UnsupportedOperationException If the device does not have
+ * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
+ */
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+ @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+ public int getDefaultNfcSubscriptionId() {
+ return callServiceReturn(() ->
+ sService.getDefaultNfcSubscriptionId(mContext.getPackageName()),
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ }
+
+ /**
* Returns the value of {@link Settings.Secure#NFC_PAYMENT_DEFAULT_COMPONENT}.
*
* @param context A context
diff --git a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
index fc482174414a..2ba93f15f7fc 100644
--- a/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/module/java/com/android/server/PackageWatchdog.java
@@ -456,7 +456,7 @@ public class PackageWatchdog {
*
* <p>This method could be called frequently if there is a severe problem on the device.
*/
- public void onPackageFailure(@NonNull List<VersionedPackage> packages,
+ public void notifyPackageFailure(@NonNull List<VersionedPackage> packages,
@FailureReasons int failureReason) {
if (packages == null) {
Slog.w(TAG, "Could not resolve a list of failing packages");
@@ -467,7 +467,7 @@ public class PackageWatchdog {
if (Flags.recoverabilityDetection()) {
if (now >= mLastMitigation
&& (now - mLastMitigation) < getMitigationWindowMs()) {
- Slog.i(TAG, "Skipping onPackageFailure mitigation");
+ Slog.i(TAG, "Skipping notifyPackageFailure mitigation");
return;
}
}
@@ -494,7 +494,7 @@ public class PackageWatchdog {
ObserverInternal observer = mAllObservers.valueAt(oIndex);
PackageHealthObserver registeredObserver = observer.registeredObserver;
if (registeredObserver != null
- && observer.onPackageFailureLocked(
+ && observer.notifyPackageFailureLocked(
versionedPackage.getPackageName())) {
MonitoredPackage p = observer.getMonitoredPackage(
versionedPackage.getPackageName());
@@ -693,7 +693,7 @@ public class PackageWatchdog {
// Check if native watchdog reported a crash
if ("1".equals(SystemProperties.get("sys.init.updatable_crashing"))) {
// We rollback all available low impact rollbacks when crash is unattributable
- onPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
+ notifyPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
// we stop polling after an attempt to execute rollback, regardless of whether the
// attempt succeeds or not
} else {
@@ -731,6 +731,25 @@ public class PackageWatchdog {
}
/**
+ * The minimum value that can be returned by any observer.
+ * It represents that no mitigations were available.
+ */
+ public static final int LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT =
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
+
+ /**
+ * The mitigation impact beyond which the user will start noticing the mitigations.
+ */
+ public static final int MEDIUM_USER_IMPACT_THRESHOLD =
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_20;
+
+ /**
+ * The mitigation impact beyond which the user impact is severely high.
+ */
+ public static final int HIGH_USER_IMPACT_THRESHOLD =
+ PackageHealthObserverImpact.USER_IMPACT_LEVEL_71;
+
+ /**
* Possible severity values of the user impact of a
* {@link PackageHealthObserver#onExecuteHealthCheckMitigation}.
* @hide
@@ -773,6 +792,11 @@ public class PackageWatchdog {
/**
* Called when health check fails for the {@code versionedPackage}.
*
+ * Note: if the returned user impact is higher than
+ * {@link #DEFAULT_HIGH_USER_IMPACT_THRESHOLD}, then
+ * {@link #onExecuteHealthCheckMitigation} would be called only in severe device conditions
+ * like boot-loop or network failure.
+ *
* @param versionedPackage the package that is failing. This may be null if a native
* service is crashing.
* @param failureReason the type of failure that is occurring.
@@ -780,8 +804,8 @@ public class PackageWatchdog {
* (including this time).
*
*
- * @return any one of {@link PackageHealthObserverImpact} to express the impact
- * to the user on {@link #onExecuteHealthCheckMitigation}
+ * @return any value greater than {@link #LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT} to express
+ * the impact of mitigation on the user in {@link #onExecuteHealthCheckMitigation}
*/
@PackageHealthObserverImpact int onHealthCheckFailed(
@Nullable VersionedPackage versionedPackage,
@@ -790,9 +814,8 @@ public class PackageWatchdog {
/**
* This would be called after {@link #onHealthCheckFailed}.
- * This is called only if current observer returned least
- * {@link PackageHealthObserverImpact} mitigation for failed health
- * check.
+ * This is called only if current observer returned least impact mitigation for failed
+ * health check.
*
* @param versionedPackage the package that is failing. This may be null if a native
* service is crashing.
@@ -811,6 +834,9 @@ public class PackageWatchdog {
*
* @param mitigationCount the number of times mitigation has been attempted for this
* boot loop (including this time).
+ *
+ * @return any value greater than {@link #LEAST_PACKAGE_HEALTH_OBSERVER_IMPACT} to express
+ * the impact of mitigation on the user in {@link #onExecuteBootLoopMitigation}
*/
default @PackageHealthObserverImpact int onBootLoop(int mitigationCount) {
return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
@@ -818,11 +844,13 @@ public class PackageWatchdog {
/**
* This would be called after {@link #onBootLoop}.
- * This is called only if current observer returned least
- * {@link PackageHealthObserverImpact} mitigation for fixing boot loop
+ * This is called only if current observer returned least impact mitigation for fixing
+ * boot loop.
*
* @param mitigationCount the number of times mitigation has been attempted for this
* boot loop (including this time).
+ *
+ * @return {@code true} if action was executed successfully, {@code false} otherwise
*/
default boolean onExecuteBootLoopMitigation(int mitigationCount) {
return false;
@@ -916,7 +944,7 @@ public class PackageWatchdog {
* effectively behave as if the explicit health check hasn't passed for {@code packageName}.
*
* <p> {@code packageName} can still be considered failed if reported by
- * {@link #onPackageFailureLocked} before the package expires.
+ * {@link #notifyPackageFailureLocked} before the package expires.
*
* <p> Triggered by components outside the system server when they are fully functional after an
* update.
@@ -1460,7 +1488,7 @@ public class PackageWatchdog {
* @hide
*/
@GuardedBy("sLock")
- public boolean onPackageFailureLocked(String packageName) {
+ public boolean notifyPackageFailureLocked(String packageName) {
if (getMonitoredPackage(packageName) == null && registeredObserver.isPersistent()
&& registeredObserver.mayObservePackage(packageName)) {
putMonitoredPackage(sPackageWatchdog.newMonitoredPackage(
diff --git a/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
index 129e47f22f38..88fe36cda395 100644
--- a/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
@@ -477,7 +477,7 @@ public class PackageWatchdog {
*
* <p>This method could be called frequently if there is a severe problem on the device.
*/
- public void onPackageFailure(@NonNull List<VersionedPackage> packages,
+ public void notifyPackageFailure(@NonNull List<VersionedPackage> packages,
@FailureReasons int failureReason) {
if (packages == null) {
Slog.w(TAG, "Could not resolve a list of failing packages");
@@ -488,7 +488,7 @@ public class PackageWatchdog {
if (Flags.recoverabilityDetection()) {
if (now >= mLastMitigation
&& (now - mLastMitigation) < getMitigationWindowMs()) {
- Slog.i(TAG, "Skipping onPackageFailure mitigation");
+ Slog.i(TAG, "Skipping notifyPackageFailure mitigation");
return;
}
}
@@ -515,7 +515,7 @@ public class PackageWatchdog {
ObserverInternal observer = mAllObservers.valueAt(oIndex);
PackageHealthObserver registeredObserver = observer.registeredObserver;
if (registeredObserver != null
- && observer.onPackageFailureLocked(
+ && observer.notifyPackageFailureLocked(
versionedPackage.getPackageName())) {
MonitoredPackage p = observer.getMonitoredPackage(
versionedPackage.getPackageName());
@@ -714,7 +714,7 @@ public class PackageWatchdog {
// Check if native watchdog reported a crash
if ("1".equals(SystemProperties.get("sys.init.updatable_crashing"))) {
// We rollback all available low impact rollbacks when crash is unattributable
- onPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
+ notifyPackageFailure(Collections.EMPTY_LIST, FAILURE_REASON_NATIVE_CRASH);
// we stop polling after an attempt to execute rollback, regardless of whether the
// attempt succeeds or not
} else {
@@ -926,7 +926,7 @@ public class PackageWatchdog {
* effectively behave as if the explicit health check hasn't passed for {@code packageName}.
*
* <p> {@code packageName} can still be considered failed if reported by
- * {@link #onPackageFailureLocked} before the package expires.
+ * {@link #notifyPackageFailureLocked} before the package expires.
*
* <p> Triggered by components outside the system server when they are fully functional after an
* update.
@@ -1253,7 +1253,7 @@ public class PackageWatchdog {
return;
}
final List<VersionedPackage> pkgList = Collections.singletonList(pkg);
- onPackageFailure(pkgList, FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
+ notifyPackageFailure(pkgList, FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
});
}
@@ -1467,7 +1467,7 @@ public class PackageWatchdog {
* @hide
*/
@GuardedBy("mLock")
- public boolean onPackageFailureLocked(String packageName) {
+ public boolean notifyPackageFailureLocked(String packageName) {
if (getMonitoredPackage(packageName) == null && registeredObserver.isPersistent()
&& registeredObserver.mayObservePackage(packageName)) {
putMonitoredPackage(sPackageWatchdog.newMonitoredPackage(
diff --git a/packages/NeuralNetworks/OWNERS b/packages/NeuralNetworks/OWNERS
new file mode 100644
index 000000000000..6b391503b5c4
--- /dev/null
+++ b/packages/NeuralNetworks/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 195575
+
+sandeepbandaru@google.com
+shivanker@google.com
+shiqing@google.com \ No newline at end of file
diff --git a/packages/SettingsLib/IntroPreference/src/com/android/settingslib/widget/IntroPreference.kt b/packages/SettingsLib/IntroPreference/src/com/android/settingslib/widget/IntroPreference.kt
index 0cdfc6610bbd..81337612e59a 100644
--- a/packages/SettingsLib/IntroPreference/src/com/android/settingslib/widget/IntroPreference.kt
+++ b/packages/SettingsLib/IntroPreference/src/com/android/settingslib/widget/IntroPreference.kt
@@ -31,7 +31,7 @@ class IntroPreference @JvmOverloads constructor(
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
-) : Preference(context, attrs, defStyleAttr, defStyleRes) {
+) : Preference(context, attrs, defStyleAttr, defStyleRes), GroupSectionDividerMixin {
private var isCollapsable: Boolean = false
private var minLines: Int = 2
diff --git a/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml b/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
index ea033a39f766..7d366f3091bc 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
+++ b/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
@@ -22,9 +22,9 @@
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical"
- android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
- android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
- android:paddingBottom="16dp">
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingBottom="@dimen/settingslib_expressive_space_small1">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
diff --git a/packages/SettingsLib/res/drawable/ic_tv_box_internal_speaker.xml b/packages/SettingsLib/res/drawable/ic_tv_box_internal_speaker.xml
new file mode 100644
index 000000000000..2a90e051b83b
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_tv_box_internal_speaker.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2022 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:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?android:attr/textColorPrimary"
+ android:autoMirrored="true">
+ <path android:fillColor="#FFFFFFFF"
+ android:pathData="M14,20.725V18.675Q16.25,18.025 17.625,16.175Q19,14.325 19,11.975Q19,9.625 17.625,7.775Q16.25,5.925 14,5.275V3.225Q17.1,3.925 19.05,6.362Q21,8.8 21,11.975Q21,15.15 19.05,17.587Q17.1,20.025 14,20.725ZM3,15V9H7L12,4V20L7,15ZM14,16V7.95Q15.175,8.5 15.838,9.6Q16.5,10.7 16.5,12Q16.5,13.275 15.838,14.362Q15.175,15.45 14,16ZM10,8.85 L7.85,11H5V13H7.85L10,15.15ZM7.5,12Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index f03014ca95e2..eaf155df4785 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1419,7 +1419,7 @@
<!-- Name of the internal speaker and mic. [CHAR LIMIT=30] -->
<string name="media_transfer_this_device_name_desktop">This computer (internal)</string>
<!-- Name of the default media output of the TV. [CHAR LIMIT=30] -->
- <string name="media_transfer_this_device_name_tv">@string/tv_media_transfer_default</string>
+ <string name="media_transfer_this_device_name_tv">This TV</string>
<!-- Name of the dock device. [CHAR LIMIT=30] -->
<string name="media_transfer_dock_speaker_device_name">Dock speaker</string>
<!-- Default name of the external device. [CHAR LIMIT=30] -->
@@ -1462,12 +1462,11 @@
<!-- Media output switcher. Subtitle for devices connected through HDMI EARC if a device name is available. [CHAR LIMIT=NONE] -->
<string name="tv_media_transfer_earc_subtitle">Connected via eARC</string>
- <!-- TV media output switcher. Title for the default audio output of the device [CHAR LIMIT=NONE] -->
- <string name="tv_media_transfer_default">TV default</string>
- <!-- TV media output switcher. Subtitle for default audio output which is HDMI, e.g. TV dongle [CHAR LIMIT=NONE] -->
- <string name="tv_media_transfer_hdmi">HDMI output</string>
- <!-- TV media output switcher. Subtitle for default audio output which is internal speaker, i.e. panel VTs [CHAR LIMIT=NONE] -->
- <string name="tv_media_transfer_internal_speakers">Internal speakers</string>
+ <!-- TV media output switcher. Subtitle for default audio output which is internal speaker [CHAR LIMIT=NONE] -->
+ <string name="tv_media_transfer_internal_speakers">Built-in speaker</string>
+
+ <!-- TV media output switcher. Title for default audio output which is HDMI, e.g. TV dongle [CHAR LIMIT=NONE] -->
+ <string name="tv_media_transfer_hdmi_title">TV Audio</string>
<!-- Warning message to tell user is have problem during profile connect, it need to turn off device and back on. [CHAR_LIMIT=NONE] -->
<string name="profile_connect_timeout_subtext">Problem connecting. Turn device off &amp; back on</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
index b3e48b26782e..fa28cf6c8a76 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java
@@ -94,6 +94,14 @@ public class HearingAidDeviceManager {
boolean setSubDeviceIfNeeded(CachedBluetoothDevice newDevice) {
final long hiSyncId = newDevice.getHiSyncId();
if (isValidHiSyncId(hiSyncId)) {
+ // The remote device supports CSIP, the other ear should be processed as a member
+ // device. Ignore hiSyncId grouping from ASHA here.
+ if (newDevice.getProfiles().stream().anyMatch(
+ profile -> profile instanceof CsipSetCoordinatorProfile)) {
+ Log.w(TAG, "Skip ASHA grouping since this device supports CSIP");
+ return false;
+ }
+
final CachedBluetoothDevice hearingAidDevice = getCachedDevice(hiSyncId);
// Just add one of the hearing aids from a pair in the list that is shown in the UI.
// Once there is another device with the same hiSyncId, to add new device as sub
@@ -161,6 +169,7 @@ public class HearingAidDeviceManager {
// device. Ignore hiSyncId grouping from ASHA here.
if (cachedDevice.getProfiles().stream().anyMatch(
profile -> profile instanceof CsipSetCoordinatorProfile)) {
+ Log.w(TAG, "Skip ASHA grouping since this device supports CSIP");
continue;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java b/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java
index 717a8ee32082..aa2ede311e23 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/DeviceIconUtil.java
@@ -33,6 +33,8 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
import android.media.MediaRoute2Info;
import android.os.SystemProperties;
import android.util.SparseIntArray;
@@ -116,14 +118,15 @@ public class DeviceIconUtil {
@SuppressLint("SwitchIntDef")
@DrawableRes
- private static int getIconResourceIdForTv(@MediaRoute2Info.Type int type) {
+ private int getIconResourceIdForTv(@MediaRoute2Info.Type int type) {
return switch (type) {
case MediaRoute2Info.TYPE_USB_DEVICE, MediaRoute2Info.TYPE_USB_HEADSET ->
R.drawable.ic_headphone;
case MediaRoute2Info.TYPE_USB_ACCESSORY -> R.drawable.ic_usb;
case MediaRoute2Info.TYPE_DOCK -> R.drawable.ic_dock_device;
- case MediaRoute2Info.TYPE_HDMI, MediaRoute2Info.TYPE_BUILTIN_SPEAKER ->
- R.drawable.ic_tv;
+ case MediaRoute2Info.TYPE_BUILTIN_SPEAKER ->
+ isPanelTv() ? R.drawable.ic_tv : R.drawable.ic_tv_box_internal_speaker;
+ case MediaRoute2Info.TYPE_HDMI -> R.drawable.ic_tv;
case MediaRoute2Info.TYPE_HDMI_ARC, MediaRoute2Info.TYPE_HDMI_EARC ->
R.drawable.ic_hdmi;
case MediaRoute2Info.TYPE_WIRED_HEADSET, MediaRoute2Info.TYPE_WIRED_HEADPHONES ->
@@ -132,6 +135,23 @@ public class DeviceIconUtil {
};
}
+ private boolean isPanelTv() {
+ if (mContext == null) {
+ // This should only happen during testing.
+ return true;
+ }
+ AudioManager audioManager = mContext.getSystemService(AudioManager.class);
+ AudioDeviceInfo[] devices = audioManager.getDevices(
+ AudioManager.GET_DEVICES_OUTPUTS);
+ // If we have an HDMI output (not ARC/eARC) we can assume it's a dongle / set top box.
+ for (AudioDeviceInfo device : devices) {
+ if (device.getType() == TYPE_HDMI) {
+ return false;
+ }
+ }
+ return true;
+ }
+
static {
AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_USB_DEVICE, MediaRoute2Info.TYPE_USB_DEVICE);
AUDIO_DEVICE_TO_MEDIA_ROUTE_TYPE.put(TYPE_USB_HEADSET, MediaRoute2Info.TYPE_USB_HEADSET);
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
index 2321097d42d7..b01b7c9048ba 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -390,6 +390,16 @@ public abstract class MediaDevice implements Comparable<MediaDevice> {
}
/**
+ * Get the {@link MediaRoute2Info.Type} of the device.
+ */
+ public int getRouteType() {
+ if (mRouteInfo == null) {
+ return TYPE_UNKNOWN;
+ }
+ return mRouteInfo.getType();
+ }
+
+ /**
* Checks if route's volume is fixed, if true, we should disable volume control for the device.
*
* @return route for this device is fixed.
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
index 4766a869e406..6ff1a99156ac 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -29,6 +29,7 @@ import static android.media.MediaRoute2Info.TYPE_WIRED_HEADSET;
import static android.media.MediaRoute2Info.TYPE_LINE_DIGITAL;
import static android.media.MediaRoute2Info.TYPE_LINE_ANALOG;
import static android.media.MediaRoute2Info.TYPE_AUX_LINE;
+
import static com.android.settingslib.media.MediaDevice.SelectionBehavior.SELECTION_BEHAVIOR_TRANSFER;
import android.Manifest;
@@ -40,6 +41,7 @@ import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiPortInfo;
import android.media.MediaRoute2Info;
import android.media.RouteListingPreference;
+import android.os.Build;
import android.os.SystemProperties;
import android.util.Log;
@@ -72,7 +74,7 @@ public class PhoneMediaDevice extends MediaDevice {
/** Returns this device name for media transfer. */
public static @NonNull String getMediaTransferThisDeviceName(@NonNull Context context) {
if (isTv(context)) {
- return context.getString(R.string.media_transfer_this_device_name_tv);
+ return Build.MODEL;
} else if (isTablet()) {
return context.getString(R.string.media_transfer_this_device_name_tablet);
} else if (inputRoutingEnabledAndIsDesktop(context)) {
@@ -110,7 +112,7 @@ public class PhoneMediaDevice extends MediaDevice {
name = getMediaTransferThisDeviceName(context);
break;
case TYPE_HDMI:
- name = context.getString(isTv ? R.string.tv_media_transfer_default :
+ name = context.getString(isTv ? R.string.tv_media_transfer_hdmi_title :
R.string.media_transfer_external_device_name);
break;
case TYPE_HDMI_ARC:
@@ -223,8 +225,6 @@ public class PhoneMediaDevice extends MediaDevice {
switch (mRouteInfo.getType()) {
case TYPE_BUILTIN_SPEAKER:
return mContext.getString(R.string.tv_media_transfer_internal_speakers);
- case TYPE_HDMI:
- return mContext.getString(R.string.tv_media_transfer_hdmi);
case TYPE_HDMI_ARC:
if (getHdmiOutDeviceName(mContext) == null) {
// Connection type is already part of the title.
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppIconCacheManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppIconCacheManagerTest.java
index 1b0e1f1236c8..013ff923e130 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppIconCacheManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/AppIconCacheManagerTest.java
@@ -16,11 +16,14 @@
package com.android.settingslib.applications;
+import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import android.graphics.drawable.Drawable;
+import android.util.Log;
import org.junit.After;
import org.junit.Before;
@@ -30,9 +33,12 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import java.util.concurrent.atomic.AtomicInteger;
+
@RunWith(RobolectricTestRunner.class)
public class AppIconCacheManagerTest {
+ private static final String TAG = "AppIconCacheManagerTest";
private static final String APP_PACKAGE_NAME = "com.test.app";
private static final String APP_PACKAGE_NAME1 = "com.test.app1";
private static final String APP_PACKAGE_NAME2 = "com.test.app2";
@@ -176,4 +182,28 @@ public class AppIconCacheManagerTest {
assertThat(mAppIconCacheManager.get(APP_PACKAGE_NAME2, APP_UID)).isNull();
assertThat(mAppIconCacheManager.get(APP_PACKAGE_NAME3, APP_UID)).isNull();
}
+
+ @Test
+ public void trimMemory_multiThread_shouldNotCrash() {
+ int numberOfTasks = 10;
+ AtomicInteger completedTasks = new AtomicInteger(0);
+
+ Runnable task =
+ () -> {
+ String threadName = Thread.currentThread().getName();
+ Log.i(TAG, "Starting thread: " + threadName);
+ AppIconCacheManager.getInstance().trimMemory(TRIM_MEMORY_BACKGROUND);
+ completedTasks.incrementAndGet();
+ Log.i(TAG, "Ending thread: " + threadName);
+ };
+
+ for (Integer i = 0; i < numberOfTasks; i++) {
+ Thread thread = new Thread(task);
+ thread.start();
+ }
+
+ while (completedTasks.get() < numberOfTasks) {
+ // Wait until all threads are finished.
+ }
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java
index 883640db5e27..5ac22a732f3c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/DeviceIconUtilTest.java
@@ -173,7 +173,7 @@ public class DeviceIconUtilTest {
public void getIconResIdFromMediaRouteType_tv_builtinSpeaker_isTv() {
assertThat(new DeviceIconUtil(/* isTv */ true)
.getIconResIdFromMediaRouteType(MediaRoute2Info.TYPE_BUILTIN_SPEAKER))
- .isEqualTo(R.drawable.ic_tv);
+ .isAnyOf(R.drawable.ic_tv, R.drawable.ic_tv_box_internal_speaker);
}
@Test
@@ -331,7 +331,7 @@ public class DeviceIconUtilTest {
public void getIconResIdFromAudioDeviceType_tv_builtinSpeaker_isTv() {
assertThat(new DeviceIconUtil(/* isTv */ true)
.getIconResIdFromAudioDeviceType(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER))
- .isEqualTo(R.drawable.ic_tv);
+ .isAnyOf(R.drawable.ic_tv, R.drawable.ic_tv_box_internal_speaker);
}
@Test
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 927a1c59cc76..1f291cdefb03 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -107,6 +107,8 @@ public class SecureSettings {
Settings.Secure.DISPLAY_WHITE_BALANCE_ENABLED,
Settings.Secure.SYNC_PARENT_SOUNDS,
Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
+ Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED,
+ Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED,
// ACCESSIBILITY_QS_TARGETS needs to be restored after ENABLED_ACCESSIBILITY_SERVICES
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 6d73ee27f076..abd5b9a4a4bb 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -160,6 +160,9 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.DISPLAY_WHITE_BALANCE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.SYNC_PARENT_SOUNDS, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
+ new InclusiveIntegerRangeValidator(0, 1));
VALIDATORS.put(Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.SYSTEM_NAVIGATION_KEYS_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.QS_TILES, TILE_LIST_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 600c36e5dfc9..5ae11bacb445 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2124,6 +2124,15 @@ class SettingsProtoDumpUtil {
SecureSettingsProto.Display.SCREEN_RESOLUTION_MODE);
p.end(displayToken);
+ final long doubleTapPowerButtonToken = p.start(SecureSettingsProto.DOUBLE_TAP_POWER_BUTTON);
+ dumpSetting(s, p,
+ Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE_ENABLED,
+ SecureSettingsProto.DoubleTapPowerButton.GESTURE_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.DOUBLE_TAP_POWER_BUTTON_GESTURE,
+ SecureSettingsProto.DoubleTapPowerButton.GESTURE);
+ p.end(doubleTapPowerButtonToken);
+
final long dozeToken = p.start(SecureSettingsProto.DOZE);
dumpSetting(s, p,
Settings.Secure.DOZE_ENABLED,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java b/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
index d835c5f5c179..b0409c037107 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/WritableNamespaces.java
@@ -33,6 +33,15 @@ import java.util.Set;
final class WritableNamespaces {
public static final Set<String> ALLOWLIST =
new ArraySet<String>(Arrays.asList(
- "exo"
+ "captive_portal_login",
+ "connectivity",
+ "exo",
+ "nearby",
+ "netd_native",
+ "network_security",
+ "on_device_personalization",
+ "tethering",
+ "tethering_u_or_later_native",
+ "thread_network"
));
}
diff --git a/packages/Shell/Android.bp b/packages/Shell/Android.bp
index 3350efc33ad8..5f810858b7cd 100644
--- a/packages/Shell/Android.bp
+++ b/packages/Shell/Android.bp
@@ -27,6 +27,7 @@ android_app {
],
flags_packages: [
"android.security.flags-aconfig",
+ "android.permission.flags-aconfig",
],
platform_apis: true,
certificate: "platform",
@@ -51,5 +52,6 @@ android_library {
manifest: "AndroidManifest.xml",
flags_packages: [
"android.security.flags-aconfig",
+ "android.permission.flags-aconfig",
],
}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index ac02af81420c..27e6bab1642d 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -981,6 +981,14 @@
<uses-permission android:name="android.permission.READ_SYSTEM_PREFERENCES" />
<uses-permission android:name="android.permission.WRITE_SYSTEM_PREFERENCES" />
+ <!-- Permissions required for CTS test - ActivityManagerForegroundServiceTypeTest -->
+ <uses-permission android:name="android.permission.health.READ_HEART_RATE"
+ android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
+ <uses-permission android:name="android.permission.health.READ_OXYGEN_SATURATION"
+ android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
+ <uses-permission android:name="android.permission.health.READ_SKIN_TEMPERATURE"
+ android:featureFlag="android.permission.flags.replace_body_sensor_permission_enabled"/>
+
<application
android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
diff --git a/packages/StatementService/Android.bp b/packages/StatementService/Android.bp
index 90e1808b7d44..39b0302beff8 100644
--- a/packages/StatementService/Android.bp
+++ b/packages/StatementService/Android.bp
@@ -38,8 +38,10 @@ android_app {
"StatementServiceParser",
"androidx.appcompat_appcompat",
"androidx.collection_collection-ktx",
+ "androidx.room_room-runtime",
"androidx.work_work-runtime",
"androidx.work_work-runtime-ktx",
"kotlinx-coroutines-android",
],
+ plugins: ["androidx.room_room-compiler-plugin"],
}
diff --git a/packages/StatementService/src/com/android/statementservice/database/Converters.kt b/packages/StatementService/src/com/android/statementservice/database/Converters.kt
new file mode 100644
index 000000000000..21ecc8b4a651
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/database/Converters.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.statementservice.database
+
+import android.content.UriRelativeFilter
+import android.content.UriRelativeFilterGroup
+import android.util.JsonReader
+import androidx.room.TypeConverter
+import org.json.JSONArray
+import org.json.JSONObject
+import java.io.StringReader
+import java.util.ArrayList
+
+class Converters {
+ companion object {
+ private const val ACTION_NAME = "action"
+ private const val FILTERS_NAME = "filters"
+ private const val URI_PART_NAME = "uriPart"
+ private const val PATTERN_TYPE_NAME = "patternType"
+ private const val FILTER_NAME = "filter"
+ }
+
+ @TypeConverter
+ fun groupsToJson(groups: List<UriRelativeFilterGroup>): String {
+ val json = JSONArray()
+ for (group in groups) {
+ json.put(groupToJson(group))
+ }
+ return json.toString()
+ }
+
+ @TypeConverter
+ fun stringToGroups(json: String): List<UriRelativeFilterGroup> {
+ val groups = ArrayList<UriRelativeFilterGroup>()
+ StringReader(json).use { stringReader ->
+ JsonReader(stringReader).use { reader ->
+ reader.beginArray()
+ while (reader.hasNext()) {
+ groups.add(parseGroup(reader))
+ }
+ reader.endArray()
+ }
+ }
+ return groups
+ }
+
+ private fun groupToJson(group: UriRelativeFilterGroup): JSONObject {
+ val jsonObject = JSONObject()
+ jsonObject.put(ACTION_NAME, group.action)
+ val filters = JSONArray()
+ for (filter in group.uriRelativeFilters) {
+ filters.put(filterToJson(filter))
+ }
+ jsonObject.put(FILTERS_NAME, filters)
+ return jsonObject
+ }
+
+ private fun filterToJson(filter: UriRelativeFilter): JSONObject {
+ val jsonObject = JSONObject()
+ jsonObject.put(URI_PART_NAME, filter.uriPart)
+ jsonObject.put(PATTERN_TYPE_NAME, filter.patternType)
+ jsonObject.put(FILTER_NAME, filter.filter)
+ return jsonObject
+ }
+
+ private fun parseGroup(reader: JsonReader): UriRelativeFilterGroup {
+ val jsonObject = JSONObject()
+ reader.beginObject()
+ while (reader.hasNext()) {
+ val name = reader.nextName()
+ when (name) {
+ ACTION_NAME -> jsonObject.put(ACTION_NAME, reader.nextInt())
+ FILTERS_NAME -> jsonObject.put(FILTERS_NAME, parseFilters(reader))
+ else -> reader.skipValue()
+ }
+ }
+ reader.endObject()
+
+ val group = UriRelativeFilterGroup(jsonObject.getInt(ACTION_NAME))
+ val filters = jsonObject.getJSONArray(FILTERS_NAME)
+ for (i in 0 until filters.length()) {
+ val filter = filters.getJSONObject(i)
+ group.addUriRelativeFilter(UriRelativeFilter(
+ filter.getInt(URI_PART_NAME),
+ filter.getInt(PATTERN_TYPE_NAME),
+ filter.getString(FILTER_NAME)
+ ))
+ }
+ return group
+ }
+
+ private fun parseFilters(reader: JsonReader): JSONArray {
+ val filters = JSONArray()
+ reader.beginArray()
+ while (reader.hasNext()) {
+ filters.put(parseFilter(reader))
+ }
+ reader.endArray()
+ return filters
+ }
+
+ private fun parseFilter(reader: JsonReader): JSONObject {
+ reader.beginObject()
+ val jsonObject = JSONObject()
+ while (reader.hasNext()) {
+ val name = reader.nextName()
+ when (name) {
+ URI_PART_NAME, PATTERN_TYPE_NAME -> jsonObject.put(name, reader.nextInt())
+ FILTER_NAME -> jsonObject.put(name, reader.nextString())
+ else -> reader.skipValue()
+ }
+ }
+ reader.endObject()
+ return jsonObject
+ }
+} \ No newline at end of file
diff --git a/packages/StatementService/src/com/android/statementservice/database/DomainGroups.kt b/packages/StatementService/src/com/android/statementservice/database/DomainGroups.kt
new file mode 100644
index 000000000000..c61666910cb4
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/database/DomainGroups.kt
@@ -0,0 +1,27 @@
+/*
+ * 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.statementservice.database
+
+import android.content.UriRelativeFilterGroup
+import androidx.room.Entity
+
+@Entity(primaryKeys = ["packageName", "domain"])
+data class DomainGroups(
+ val packageName: String,
+ val domain: String,
+ val groups: List<UriRelativeFilterGroup>
+) \ No newline at end of file
diff --git a/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDao.kt b/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDao.kt
new file mode 100644
index 000000000000..3b4dcea48180
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDao.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.statementservice.database
+
+import androidx.room.Dao
+import androidx.room.Insert
+import androidx.room.Query
+
+@Dao
+interface DomainGroupsDao {
+ @Query("SELECT * FROM DomainGroups WHERE packageName = :packageName")
+ fun getDomainGroups(packageName: String): List<DomainGroups>
+
+ @Insert
+ fun insertDomainGroups(vararg domainGroups: DomainGroups)
+
+ @Query("DELETE FROM DomainGroups WHERE packageName = :packageName AND domain = :domain")
+ fun clear(packageName: String, domain: String)
+
+ @Query("DELETE FROM DomainGroups WHERE packageName = :packageName")
+ fun clear(packageName: String)
+} \ No newline at end of file
diff --git a/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDatabase.kt b/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDatabase.kt
new file mode 100644
index 000000000000..39833f6bc80b
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/database/DomainGroupsDatabase.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.statementservice.database
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.room.TypeConverters
+
+@Database(entities = [DomainGroups::class], version = 1)
+@TypeConverters(Converters::class)
+abstract class DomainGroupsDatabase : RoomDatabase() {
+ companion object {
+ private const val DATABASE_NAME = "domain-groups"
+ @Volatile
+ private var instance: DomainGroupsDatabase? = null
+
+ fun getInstance(context: Context) = instance ?: synchronized(this) {
+ instance ?: Room.databaseBuilder(
+ context,
+ DomainGroupsDatabase::class.java, DATABASE_NAME
+ ).build().also { instance = it }
+ }
+ }
+ abstract fun domainGroupsDao(): DomainGroupsDao
+} \ No newline at end of file
diff --git a/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt b/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt
index acb54f6093de..0d7a1fdbcfb8 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/DomainVerificationReceiverV1.kt
@@ -22,6 +22,7 @@ import android.content.pm.PackageManager
import androidx.work.ExistingWorkPolicy
import androidx.work.WorkManager
import com.android.statementservice.domain.worker.CollectV1Worker
+import com.android.statementservice.domain.worker.GroupUpdateV1Worker
import com.android.statementservice.domain.worker.SingleV1RequestWorker
/**
@@ -67,7 +68,7 @@ class DomainVerificationReceiverV1 : BaseDomainVerificationReceiver() {
}
}
- //clear sp before enqueue unique work since policy is REPLACE
+ // clear sp before enqueue unique work since policy is REPLACE
val deContext = context.createDeviceProtectedStorageContext()
val editor = deContext?.getSharedPreferences(packageName, Context.MODE_PRIVATE)?.edit()
editor?.clear()?.apply()
@@ -78,6 +79,7 @@ class DomainVerificationReceiverV1 : BaseDomainVerificationReceiver() {
workRequests
)
.then(CollectV1Worker.buildRequest(verificationId, packageName))
+ .then(GroupUpdateV1Worker.buildRequest(packageName))
.enqueue()
}
}
diff --git a/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt b/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt
index 29f844fb1a5d..6914347544de 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/DomainVerifier.kt
@@ -24,6 +24,7 @@ import androidx.collection.LruCache
import com.android.statementservice.network.retriever.StatementRetriever
import com.android.statementservice.retriever.AbstractAsset
import com.android.statementservice.retriever.AbstractAssetMatcher
+import com.android.statementservice.retriever.Statement
import com.android.statementservice.utils.Result
import com.android.statementservice.utils.StatementUtils
import com.android.statementservice.utils.component1
@@ -87,10 +88,10 @@ class DomainVerifier private constructor(
host: String,
packageName: String,
network: Network? = null
- ): Pair<WorkResult, VerifyStatus> {
+ ): Triple<WorkResult, VerifyStatus, Statement?> {
val assetMatcher = synchronized(targetAssetCache) { targetAssetCache[packageName] }
.takeIf { it!!.isPresent }
- ?: return WorkResult.failure() to VerifyStatus.FAILURE_PACKAGE_MANAGER
+ ?: return Triple(WorkResult.failure(), VerifyStatus.FAILURE_PACKAGE_MANAGER, null)
return verifyHost(host, assetMatcher.get(), network)
}
@@ -98,34 +99,34 @@ class DomainVerifier private constructor(
host: String,
assetMatcher: AbstractAssetMatcher,
network: Network? = null
- ): Pair<WorkResult, VerifyStatus> {
+ ): Triple<WorkResult, VerifyStatus, Statement?> {
var exception: Exception? = null
val resultAndStatus = try {
val sourceAsset = StatementUtils.createWebAssetString(host)
.let(AbstractAsset::create)
val result = retriever.retrieve(sourceAsset, network)
- ?: return WorkResult.success() to VerifyStatus.FAILURE_UNKNOWN
+ ?: return Triple(WorkResult.success(), VerifyStatus.FAILURE_UNKNOWN, null)
when (result.responseCode) {
HttpURLConnection.HTTP_MOVED_PERM,
HttpURLConnection.HTTP_MOVED_TEMP -> {
- WorkResult.failure() to VerifyStatus.FAILURE_REDIRECT
+ Triple(WorkResult.failure(), VerifyStatus.FAILURE_REDIRECT, null)
}
else -> {
- val isVerified = result.statements.any { statement ->
+ val statement = result.statements.firstOrNull { statement ->
(StatementUtils.RELATION.matches(statement.relation) &&
assetMatcher.matches(statement.target))
}
- if (isVerified) {
- WorkResult.success() to VerifyStatus.SUCCESS
+ if (statement != null) {
+ Triple(WorkResult.success(), VerifyStatus.SUCCESS, statement)
} else {
- WorkResult.failure() to VerifyStatus.FAILURE_REJECTED_BY_SERVER
+ Triple(WorkResult.failure(), VerifyStatus.FAILURE_REJECTED_BY_SERVER, statement)
}
}
}
} catch (e: Exception) {
exception = e
- WorkResult.retry() to VerifyStatus.FAILURE_UNKNOWN
+ Triple(WorkResult.retry(), VerifyStatus.FAILURE_UNKNOWN, null)
}
if (DEBUG) {
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/BaseRequestWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/BaseRequestWorker.kt
index a17f9c9186ff..64d2d98b931b 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/BaseRequestWorker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/BaseRequestWorker.kt
@@ -17,9 +17,12 @@
package com.android.statementservice.domain.worker
import android.content.Context
+import android.content.UriRelativeFilterGroup
+import android.content.pm.verify.domain.DomainVerificationInfo
import android.content.pm.verify.domain.DomainVerificationManager
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
+import com.android.statementservice.database.DomainGroupsDatabase
import com.android.statementservice.domain.DomainVerifier
abstract class BaseRequestWorker(
@@ -27,8 +30,19 @@ abstract class BaseRequestWorker(
protected val params: WorkerParameters
) : CoroutineWorker(appContext, params) {
+ protected val database = DomainGroupsDatabase.getInstance(appContext).domainGroupsDao()
+
protected val verificationManager =
appContext.getSystemService(DomainVerificationManager::class.java)!!
protected val verifier = DomainVerifier.getInstance(appContext)
+
+ protected fun updateUriRelativeFilterGroups(packageName: String, domainGroupUpdates: Map<String, List<UriRelativeFilterGroup>>) {
+ val verifiedDomains = verificationManager.getDomainVerificationInfo(packageName)?.hostToStateMap?.filterValues {
+ it == DomainVerificationInfo.STATE_SUCCESS || it == DomainVerificationInfo.STATE_MODIFIABLE_VERIFIED
+ }?.keys?.toList() ?: emptyList()
+ val domainGroups = verificationManager.getUriRelativeFilterGroups(packageName, verifiedDomains)
+ domainGroupUpdates.forEach { (domain, groups) -> domainGroups[domain] = groups }
+ verificationManager.setUriRelativeFilterGroups(packageName, domainGroups)
+ }
}
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/GroupUpdateV1Worker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/GroupUpdateV1Worker.kt
new file mode 100644
index 000000000000..f53dfc47acaa
--- /dev/null
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/GroupUpdateV1Worker.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.statementservice.domain.worker
+
+import android.content.Context
+import androidx.work.Data
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.WorkerParameters
+import kotlinx.coroutines.coroutineScope
+
+class GroupUpdateV1Worker(appContext: Context, params: WorkerParameters) :
+ BaseRequestWorker(appContext, params) {
+
+ companion object {
+
+ private const val PACKAGE_NAME_KEY = "packageName"
+
+ fun buildRequest(packageName: String) = OneTimeWorkRequestBuilder<GroupUpdateV1Worker>()
+ .setInputData(
+ Data.Builder()
+ .putString(PACKAGE_NAME_KEY, packageName)
+ .build()
+ )
+ .build()
+ }
+
+ override suspend fun doWork() = coroutineScope {
+ val packageName = params.inputData.getString(PACKAGE_NAME_KEY)!!
+ updateUriRelativeFilterGroups(packageName)
+ Result.success()
+ }
+
+ private fun updateUriRelativeFilterGroups(packageName: String) {
+ val groupUpdates = database.getDomainGroups(packageName)
+ updateUriRelativeFilterGroups(
+ packageName,
+ groupUpdates.associateBy({it.domain}, {it.groups})
+ )
+ database.clear(packageName)
+ }
+} \ No newline at end of file
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt
index 61ab2c264e6a..f83601a7807b 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/RetryRequestWorker.kt
@@ -17,10 +17,13 @@
package com.android.statementservice.domain.worker
import android.content.Context
+import android.content.UriRelativeFilterGroup
+import android.content.pm.verify.domain.DomainVerificationManager
import androidx.work.NetworkType
import androidx.work.WorkerParameters
import com.android.statementservice.domain.VerifyStatus
import com.android.statementservice.utils.AndroidUtils
+import com.android.statementservice.utils.StatementUtils
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
@@ -36,7 +39,13 @@ class RetryRequestWorker(
params: WorkerParameters
) : BaseRequestWorker(appContext, params) {
- data class VerifyResult(val domainSetId: UUID, val host: String, val status: VerifyStatus)
+ data class VerifyResult(
+ val domainSetId: UUID,
+ val host: String,
+ val status: VerifyStatus,
+ val packageName: String,
+ val groups: List<UriRelativeFilterGroup>
+ )
override suspend fun doWork() = coroutineScope {
if (!AndroidUtils.isReceiverV2Enabled(appContext)) {
@@ -49,8 +58,11 @@ class RetryRequestWorker(
.map { (domainSetId, packageName, host) ->
async {
if (isActive && !isStopped) {
- val (_, status) = verifier.verifyHost(host, packageName, params.network)
- VerifyResult(domainSetId, host, status)
+ val (_, status, statement) = verifier.verifyHost(host, packageName, params.network)
+ val groups = statement?.dynamicAppLinkComponents.orEmpty().map {
+ StatementUtils.createUriRelativeFilterGroup(it)
+ }
+ VerifyResult(domainSetId, host, status, packageName, groups)
} else {
// If the job gets cancelled, stop the remaining hosts, but continue the
// job to commit the results for hosts that were already requested.
@@ -60,17 +72,25 @@ class RetryRequestWorker(
}
.awaitAll()
.filterNotNull() // TODO(b/159952358): Fast fail packages which can't be retrieved.
- .groupBy { it.domainSetId }
- .forEach { (domainSetId, resultsById) ->
- resultsById.groupBy { it.status }
- .mapValues { it.value.map(VerifyResult::host).toSet() }
- .forEach { (status, hosts) ->
- verificationManager.setDomainVerificationStatus(
- domainSetId,
- hosts,
- status.value
- )
+ .groupBy { it.packageName }
+ .forEach { (packageName, resultsByName) ->
+ val groupUpdates = mutableMapOf<String, List<UriRelativeFilterGroup>>()
+ resultsByName.groupBy { it.domainSetId }
+ .forEach { (domainSetId, resultsById) ->
+ resultsById.groupBy { it.status }
+ .forEach { (status, verifyResults) ->
+ val error = verificationManager.setDomainVerificationStatus(
+ domainSetId,
+ verifyResults.map(VerifyResult::host).toSet(),
+ status.value
+ )
+ if (error == DomainVerificationManager.STATUS_OK
+ && status == VerifyStatus.SUCCESS) {
+ verifyResults.forEach { groupUpdates[it.host] = it.groups }
+ }
+ }
}
+ updateUriRelativeFilterGroups(packageName, groupUpdates)
}
// Succeed regardless of results since this retry is best effort and not required
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt
index 7a198cb59ca4..253a162a73a2 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV1RequestWorker.kt
@@ -22,7 +22,9 @@ import androidx.work.Data
import androidx.work.OneTimeWorkRequest
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkerParameters
+import com.android.statementservice.database.DomainGroups
import com.android.statementservice.utils.AndroidUtils
+import com.android.statementservice.utils.StatementUtils
import kotlinx.coroutines.coroutineScope
class SingleV1RequestWorker(appContext: Context, params: WorkerParameters) :
@@ -60,7 +62,9 @@ class SingleV1RequestWorker(appContext: Context, params: WorkerParameters) :
val packageName = params.inputData.getString(PACKAGE_NAME_KEY)!!
val host = params.inputData.getString(HOST_KEY)!!
- val (result, status) = verifier.verifyHost(host, packageName, params.network)
+ database.clear(packageName, host)
+
+ val (result, status, statement) = verifier.verifyHost(host, packageName, params.network)
if (DEBUG) {
Log.d(
@@ -75,6 +79,10 @@ class SingleV1RequestWorker(appContext: Context, params: WorkerParameters) :
val deContext = appContext.createDeviceProtectedStorageContext()
val sp = deContext?.getSharedPreferences(packageName, Context.MODE_PRIVATE)
sp?.edit()?.putInt("$HOST_SUCCESS_PREFIX$host", status.value)?.apply()
+ val groups = statement?.dynamicAppLinkComponents.orEmpty().map {
+ StatementUtils.createUriRelativeFilterGroup(it)
+ }
+ database.insertDomainGroups(DomainGroups(packageName, host, groups))
Result.success()
}
is Result.Failure -> {
diff --git a/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV2RequestWorker.kt b/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV2RequestWorker.kt
index 562b132d36d6..8b1347a69932 100644
--- a/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV2RequestWorker.kt
+++ b/packages/StatementService/src/com/android/statementservice/domain/worker/SingleV2RequestWorker.kt
@@ -22,6 +22,7 @@ import androidx.work.OneTimeWorkRequest
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkerParameters
import com.android.statementservice.utils.AndroidUtils
+import com.android.statementservice.utils.StatementUtils
import kotlinx.coroutines.coroutineScope
import java.util.UUID
@@ -59,9 +60,13 @@ class SingleV2RequestWorker(appContext: Context, params: WorkerParameters) :
val packageName = params.inputData.getString(PACKAGE_NAME_KEY)!!
val host = params.inputData.getString(HOST_KEY)!!
- val (result, status) = verifier.verifyHost(host, packageName, params.network)
+ val (result, status, statement) = verifier.verifyHost(host, packageName, params.network)
verificationManager.setDomainVerificationStatus(domainSetId, setOf(host), status.value)
+ val groups = statement?.dynamicAppLinkComponents.orEmpty().map {
+ StatementUtils.createUriRelativeFilterGroup(it)
+ }
+ updateUriRelativeFilterGroups(packageName, mapOf(host to groups))
result
}
diff --git a/packages/StatementService/src/com/android/statementservice/network/retriever/StatementParser.kt b/packages/StatementService/src/com/android/statementservice/network/retriever/StatementParser.kt
index ad137400fa86..d10cb0f91c11 100644
--- a/packages/StatementService/src/com/android/statementservice/network/retriever/StatementParser.kt
+++ b/packages/StatementService/src/com/android/statementservice/network/retriever/StatementParser.kt
@@ -39,6 +39,11 @@ object StatementParser {
private const val FIELD_NOT_STRING_FORMAT_STRING = "Expected %s to be string."
private const val FIELD_NOT_ARRAY_FORMAT_STRING = "Expected %s to be array."
+ private const val COMMENTS_NAME = "comments"
+ private const val EXCLUDE_NAME = "exclude"
+ private const val FRAGMENT_NAME = "#"
+ private const val QUERY_NAME = "?"
+ private const val PATH_NAME = "/"
/**
* Parses a JSON array of statements.
@@ -99,9 +104,7 @@ object StatementParser {
FIELD_NOT_ARRAY_FORMAT_STRING.format(StatementUtils.ASSET_DESCRIPTOR_FIELD_RELATION)
)
val target = AssetFactory.create(targetObject)
- val dynamicAppLinkComponents = parseDynamicAppLinkComponents(
- statement.optJSONObject(StatementUtils.ASSET_DESCRIPTOR_FIELD_RELATION_EXTENSIONS)
- )
+ val dynamicAppLinkComponents = parseDynamicAppLinkComponents(statement)
val statements = (0 until relations.length())
.map { relations.getString(it) }
@@ -129,13 +132,13 @@ object StatementParser {
}
private fun parseComponent(component: JSONObject): DynamicAppLinkComponent {
- val query = component.optJSONObject("?")
+ val query = component.optJSONObject(QUERY_NAME)
return DynamicAppLinkComponent.create(
- component.optBoolean("exclude", false),
- component.optString("#"),
- component.optString("/"),
+ component.optBoolean(EXCLUDE_NAME, false),
+ if (component.has(FRAGMENT_NAME)) component.getString(FRAGMENT_NAME) else null,
+ if (component.has(PATH_NAME)) component.getString(PATH_NAME) else null,
query?.keys()?.asSequence()?.associateWith { query.getString(it) },
- component.optString("comments")
+ component.optString(COMMENTS_NAME)
)
}
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/DynamicAppLinkComponent.java b/packages/StatementService/src/com/android/statementservice/retriever/DynamicAppLinkComponent.java
index dc27e125e204..c32f1949fed4 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/DynamicAppLinkComponent.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/DynamicAppLinkComponent.java
@@ -130,7 +130,7 @@ public final class DynamicAppLinkComponent {
@Override
public String toString() {
StringBuilder statement = new StringBuilder();
- statement.append("HandleAllUriRule: ");
+ statement.append("DynamicAppLinkComponent: ");
statement.append(mExclude);
statement.append(", ");
statement.append(mFragment);
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/JsonParser.java b/packages/StatementService/src/com/android/statementservice/retriever/JsonParser.java
index 7635e8234dc0..ab1853c1d3ae 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/JsonParser.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/JsonParser.java
@@ -24,8 +24,6 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
/**
* A helper class that creates a {@link JSONObject} from a {@link JsonReader}.
@@ -48,7 +46,7 @@ public final class JsonParser {
JsonToken token = reader.peek();
if (token.equals(JsonToken.BEGIN_ARRAY)) {
- output.put(fieldName, new JSONArray(parseArray(reader)));
+ output.put(fieldName, parseArray(reader));
} else if (token.equals(JsonToken.STRING)) {
output.put(fieldName, reader.nextString());
} else if (token.equals(JsonToken.BEGIN_OBJECT)) {
@@ -57,9 +55,11 @@ public final class JsonParser {
} catch (JSONException e) {
errorMsg = e.getMessage();
}
+ } else if (token.equals(JsonToken.BOOLEAN)) {
+ output.put(fieldName, reader.nextBoolean());
} else {
reader.skipValue();
- errorMsg = "Unsupported value type.";
+ errorMsg = "Unsupported value type: " + token;
}
}
reader.endObject();
@@ -72,17 +72,36 @@ public final class JsonParser {
}
/**
- * Parses one string array from the {@link JsonReader}.
+ * Parses one JSON array from the {@link JsonReader}.
*/
- public static List<String> parseArray(JsonReader reader) throws IOException {
- ArrayList<String> output = new ArrayList<>();
+ public static JSONArray parseArray(JsonReader reader) throws IOException, JSONException {
+ JSONArray output = new JSONArray();
+ String errorMsg = null;
reader.beginArray();
while (reader.hasNext()) {
- output.add(reader.nextString());
+ JsonToken token = reader.peek();
+ if (token.equals(JsonToken.BEGIN_ARRAY)) {
+ output.put(parseArray(reader));
+ } else if (token.equals(JsonToken.STRING)) {
+ output.put(reader.nextString());
+ } else if (token.equals(JsonToken.BEGIN_OBJECT)) {
+ try {
+ output.put(parse(reader));
+ } catch (JSONException e) {
+ errorMsg = e.getMessage();
+ }
+ } else {
+ reader.skipValue();
+ errorMsg = "Unsupported value type: " + token;
+ }
}
reader.endArray();
+ if (errorMsg != null) {
+ throw new JSONException(errorMsg);
+ }
+
return output;
}
}
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
index c71ef8360008..129dd9b3c14d 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
@@ -36,7 +36,6 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
-import com.android.systemui.accessibility.accessibilitymenu.Flags;
import com.android.systemui.accessibility.accessibilitymenu.R;
/**
@@ -62,10 +61,8 @@ public class A11yMenuSettingsActivity extends FragmentActivity {
((TextView) findViewById(R.id.action_bar_title)).setText(
getResources().getString(R.string.accessibility_menu_settings_name)
);
- if (Flags.actionBarWrapContent()) {
- setHeightWrapContent(findViewById(com.android.internal.R.id.action_bar));
- setHeightWrapContent(findViewById(com.android.internal.R.id.action_bar_container));
- }
+ setHeightWrapContent(findViewById(com.android.internal.R.id.action_bar));
+ setHeightWrapContent(findViewById(com.android.internal.R.id.action_bar_container));
}
private void setHeightWrapContent(View view) {
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 3541742e2bb7..e59fe47194da 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1215,6 +1215,13 @@ flag {
}
flag {
+ name: "glanceable_hub_v2"
+ namespace: "systemui"
+ description: "Gates the refreshed glanceable hub experience that also brings the glanceable hub to mobile phones"
+ bug: "375689917"
+}
+
+flag {
name: "dream_overlay_updated_font"
namespace: "systemui"
description: "Flag to enable updated font settings for dream overlay"
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
index eee0cafd34fe..f1cbba7272b0 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -17,6 +17,7 @@
package com.android.systemui.animation
import android.app.ActivityManager
+import android.app.ActivityOptions
import android.app.ActivityTaskManager
import android.app.PendingIntent
import android.app.TaskInfo
@@ -434,8 +435,7 @@ constructor(
private fun cleanUp() {
cleanUpRunnable?.run()
}
- },
- initializeLazily = longLivedReturnAnimationsEnabled(),
+ }
)
// mTypeSet and mModes match back signals only, and not home. This is on purpose, because
@@ -478,8 +478,8 @@ constructor(
/** Create a new animation [Runner] controlled by [controller]. */
@VisibleForTesting
@JvmOverloads
- fun createRunner(controller: Controller, initializeLazily: Boolean = false): Runner {
- if (initializeLazily) assertLongLivedReturnAnimations()
+ fun createRunner(controller: Controller, longLived: Boolean = false): Runner {
+ if (longLived) assertLongLivedReturnAnimations()
// Make sure we use the modified timings when animating a dialog into an app.
val transitionAnimator =
@@ -489,13 +489,7 @@ constructor(
transitionAnimator
}
- return Runner(
- controller,
- callback!!,
- transitionAnimator,
- lifecycleListener,
- initializeLazily,
- )
+ return Runner(controller, callback!!, transitionAnimator, lifecycleListener, longLived)
}
interface PendingIntentStarter {
@@ -699,7 +693,7 @@ constructor(
}
val launchRemoteTransition =
RemoteTransition(
- OriginTransition(createRunner(controller, initializeLazily = true)),
+ OriginTransition(createRunner(controller, longLived = true)),
"${cookie}_launchTransition",
)
transitionRegister.register(launchFilter, launchRemoteTransition, includeTakeover = true)
@@ -721,7 +715,7 @@ constructor(
}
val returnRemoteTransition =
RemoteTransition(
- OriginTransition(createRunner(returnController, initializeLazily = true)),
+ OriginTransition(createRunner(returnController, longLived = true)),
"${cookie}_returnTransition",
)
transitionRegister.register(returnFilter, returnRemoteTransition, includeTakeover = true)
@@ -910,14 +904,22 @@ constructor(
@VisibleForTesting
inner class Runner(
- private val controller: Controller,
+ /**
+ * This can hold a reference to a view, so it needs to be cleaned up and can't be held on to
+ * forever when ![longLived].
+ */
+ private var controller: Controller?,
private val callback: Callback,
/** The animator to use to animate the window transition. */
private val transitionAnimator: TransitionAnimator,
/** Listener for animation lifecycle events. */
private val listener: Listener? = null,
- /** Whether the internal [delegate] should be initialized lazily. */
- private val initializeLazily: Boolean = false,
+ /**
+ * Whether the internal should be kept around after execution for later usage. IMPORTANT:
+ * should always be false if this [Runner] is to be used directly with [ActivityOptions]
+ * (i.e. for ephemeral launches), or the controller will leak its view.
+ */
+ private val longLived: Boolean = false,
) : IRemoteAnimationRunner.Stub() {
// This is being passed across IPC boundaries and cycles (through PendingIntentRecords,
// etc.) are possible. So we need to make sure we drop any references that might
@@ -926,7 +928,7 @@ constructor(
init {
delegate = null
- if (!initializeLazily) {
+ if (!longLived) {
// Ephemeral launches bundle the runner with the launch request (instead of being
// registered ahead of time for later use). This means that there could be a timeout
// between creation and invocation, so the delegate needs to exist from the
@@ -1004,16 +1006,17 @@ constructor(
@AnyThread
private fun maybeSetUp() {
- if (!initializeLazily || delegate != null) return
+ if (!longLived || delegate != null) return
createDelegate()
}
@AnyThread
private fun createDelegate() {
+ if (controller == null) return
delegate =
AnimationDelegate(
mainExecutor,
- controller,
+ controller!!,
callback,
DelegatingAnimationCompletionListener(listener, this::dispose),
transitionAnimator,
@@ -1025,7 +1028,12 @@ constructor(
fun dispose() {
// Drop references to animation controller once we're done with the animation
// to avoid leaking.
- mainExecutor.execute { delegate = null }
+ mainExecutor.execute {
+ delegate = null
+ // When long lived, the same Runner can be used more than once. In this case we need
+ // to keep the controller around so we can rebuild the delegate on demand.
+ if (!longLived) controller = null
+ }
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index 87e9c427d695..4705d8dd86c4 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -44,6 +44,7 @@ import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.observableTransitionState
import com.android.compose.animation.scene.transitions
+import com.android.systemui.Flags.communalHubOnMobile
import com.android.systemui.communal.shared.model.CommunalBackgroundType
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalTransitionKeys
@@ -186,15 +187,19 @@ fun CommunalContainer(
) {
scene(
CommunalScenes.Blank,
- userActions = mapOf(Swipe.Start(fromSource = Edge.End) to CommunalScenes.Communal),
+ userActions =
+ if (communalHubOnMobile()) emptyMap()
+ else mapOf(Swipe.Start(fromSource = Edge.End) to CommunalScenes.Communal),
) {
// This scene shows nothing only allowing for transitions to the communal scene.
Box(modifier = Modifier.fillMaxSize())
}
- val userActions = mapOf(Swipe.End to CommunalScenes.Blank)
-
- scene(CommunalScenes.Communal, userActions = userActions) {
+ scene(
+ CommunalScenes.Communal,
+ userActions =
+ if (communalHubOnMobile()) emptyMap() else mapOf(Swipe.End to CommunalScenes.Blank),
+ ) {
CommunalScene(
backgroundType = backgroundType,
colors = colors,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
index 2a2c2fc4934e..105e8dadfafb 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
@@ -21,7 +21,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -70,10 +69,7 @@ constructor(
override val id: String = "default"
@Composable
- override fun SceneScope.Content(
- viewModel: LockscreenContentViewModel,
- modifier: Modifier,
- ) {
+ override fun SceneScope.Content(viewModel: LockscreenContentViewModel, modifier: Modifier) {
val isUdfpsVisible = viewModel.isUdfpsVisible
val isShadeLayoutWide by viewModel.isShadeLayoutWide.collectAsStateWithLifecycle()
val unfoldTranslations by viewModel.unfoldTranslations.collectAsStateWithLifecycle()
@@ -85,22 +81,18 @@ constructor(
with(notificationSection) { HeadsUpNotifications() }
}
- LockscreenLongPress(
- viewModel = viewModel.touchHandling,
- modifier = modifier,
- ) { onSettingsMenuPlaced ->
+ LockscreenLongPress(viewModel = viewModel.touchHandling, modifier = modifier) {
+ onSettingsMenuPlaced ->
Layout(
content = {
// Constrained to above the lock icon.
- Column(
- modifier = Modifier.fillMaxSize(),
- ) {
+ Column(modifier = Modifier.fillMaxSize()) {
with(statusBarSection) {
StatusBar(
modifier =
Modifier.fillMaxWidth()
.padding(
- horizontal = { unfoldTranslations.start.roundToInt() },
+ horizontal = { unfoldTranslations.start.roundToInt() }
)
)
}
@@ -109,13 +101,14 @@ constructor(
with(topAreaSection) {
DefaultClockLayout(
smartSpacePaddingTop = viewModel::getSmartSpacePaddingTop,
+ isShadeLayoutWide = isShadeLayoutWide,
modifier =
Modifier.thenIf(isShadeLayoutWide) {
Modifier.fillMaxWidth(0.5f)
}
.graphicsLayer {
translationX = unfoldTranslations.start
- }
+ },
)
}
if (isShadeLayoutWide && !isBypassEnabled) {
@@ -127,7 +120,7 @@ constructor(
modifier =
Modifier.fillMaxWidth(0.5f)
.fillMaxHeight()
- .align(alignment = Alignment.TopEnd)
+ .align(alignment = Alignment.TopEnd),
)
}
}
@@ -142,7 +135,7 @@ constructor(
AodNotificationIcons(
modifier =
Modifier.align(alignment = Alignment.TopStart)
- .padding(start = aodIconPadding),
+ .padding(start = aodIconPadding)
)
Notifications(
areNotificationsVisible = areNotificationsVisible,
@@ -152,7 +145,7 @@ constructor(
}
} else {
AodNotificationIcons(
- modifier = Modifier.padding(start = aodIconPadding),
+ modifier = Modifier.padding(start = aodIconPadding)
)
}
}
@@ -205,11 +198,7 @@ constructor(
val endShortcutMeasurable = measurables[4]
val settingsMenuMeasurable = measurables[5]
- val noMinConstraints =
- constraints.copy(
- minWidth = 0,
- minHeight = 0,
- )
+ val noMinConstraints = constraints.copy(minWidth = 0, minHeight = 0)
val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints)
val lockIconBounds =
IntRect(
@@ -235,14 +224,8 @@ constructor(
val settingsMenuPlaceable = settingsMenuMeasurable.measure(noMinConstraints)
layout(constraints.maxWidth, constraints.maxHeight) {
- aboveLockIconPlaceable.place(
- x = 0,
- y = 0,
- )
- lockIconPlaceable.place(
- x = lockIconBounds.left,
- y = lockIconBounds.top,
- )
+ aboveLockIconPlaceable.place(x = 0, y = 0)
+ lockIconPlaceable.place(x = lockIconBounds.left, y = lockIconBounds.top)
belowLockIconPlaceable.place(
x = 0,
y = constraints.maxHeight - belowLockIconPlaceable.height,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt
index 3ca2b9c1d86c..4a9f44b74099 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/MediaCarouselSection.kt
@@ -17,9 +17,11 @@
package com.android.systemui.keyguard.ui.composable.section
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.dimensionResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.keyguard.ui.viewmodel.KeyguardMediaViewModel
@@ -27,6 +29,7 @@ import com.android.systemui.media.controls.ui.composable.MediaCarousel
import com.android.systemui.media.controls.ui.controller.MediaCarouselController
import com.android.systemui.media.controls.ui.view.MediaHost
import com.android.systemui.media.dagger.MediaModule
+import com.android.systemui.res.R
import javax.inject.Inject
import javax.inject.Named
@@ -39,13 +42,22 @@ constructor(
) {
@Composable
- fun SceneScope.KeyguardMediaCarousel() {
+ fun SceneScope.KeyguardMediaCarousel(
+ isShadeLayoutWide: Boolean,
+ modifier: Modifier = Modifier,
+ ) {
val isMediaVisible by keyguardMediaViewModel.isMediaVisible.collectAsStateWithLifecycle()
-
+ val horizontalPadding =
+ if (isShadeLayoutWide) {
+ dimensionResource(id = R.dimen.notification_side_paddings)
+ } else {
+ dimensionResource(id = R.dimen.notification_side_paddings) +
+ dimensionResource(id = R.dimen.notification_panel_margin_horizontal)
+ }
MediaCarousel(
isVisible = isMediaVisible,
mediaHost = mediaHost,
- modifier = Modifier.fillMaxWidth(),
+ modifier = modifier.fillMaxWidth().padding(horizontal = horizontalPadding),
carouselController = mediaCarouselController,
)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
index afa92f2533ce..db33e7c628d7 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/TopAreaSection.kt
@@ -63,6 +63,7 @@ constructor(
@Composable
fun SceneScope.DefaultClockLayout(
smartSpacePaddingTop: (Resources) -> Int,
+ isShadeLayoutWide: Boolean,
modifier: Modifier = Modifier,
) {
val currentClockLayout by clockViewModel.currentClockLayout.collectAsStateWithLifecycle()
@@ -128,7 +129,7 @@ constructor(
)
}
}
- with(mediaCarouselSection) { KeyguardMediaCarousel() }
+ with(mediaCarouselSection) { KeyguardMediaCarousel(isShadeLayoutWide) }
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
index e725ce589f3e..58336c2e9d41 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt
@@ -79,8 +79,8 @@ object QuickSettings {
val MediaLandscapeTopOffset = ValueKey("MediaLandscapeTopOffset")
object MediaOffset {
- // Brightness + padding
- val InQS = 92.dp
+ // Brightness
+ val InQS = 60.dp
val Default = 0.dp
@Composable
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index 0e7165c7f3ec..52adaf2a5b5d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -74,6 +74,7 @@ import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.animateSceneDpAsState
import com.android.compose.animation.scene.animateSceneFloatAsState
import com.android.compose.animation.scene.content.state.TransitionState
+import com.android.compose.modifiers.padding
import com.android.compose.modifiers.thenIf
import com.android.compose.windowsizeclass.LocalWindowSizeClass
import com.android.systemui.battery.BatteryMeterViewController
@@ -379,7 +380,11 @@ private fun SceneScope.QuickSettingsScene(
mediaHost = mediaHost,
modifier =
Modifier.fillMaxWidth()
- .layoutId(QSMediaMeasurePolicy.LayoutId.Media),
+ .layoutId(QSMediaMeasurePolicy.LayoutId.Media)
+ .padding(
+ horizontal =
+ dimensionResource(id = R.dimen.qs_horizontal_margin)
+ ),
carouselController = mediaCarouselController,
)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
index 26c827a5417c..f84865ffc6af 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeOverlay.kt
@@ -168,7 +168,6 @@ fun SceneScope.QuickSettingsLayout(
modifier =
Modifier.fillMaxWidth()
.heightIn(max = QuickSettingsShade.Dimensions.GridMaxHeight),
- viewModel.editModeViewModel::startEditing,
)
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index ae5dd8abb82e..5fb9416cf35b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -19,12 +19,17 @@ package com.android.systemui.scene.ui.composable
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.compose.animation.scene.animateContentDpAsState
import com.android.compose.animation.scene.animateContentFloatAsState
+import com.android.compose.animation.scene.content.state.TransitionState
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.rememberViewModel
@@ -63,9 +68,25 @@ constructor(
}
@Composable
- override fun SceneScope.Content(
- modifier: Modifier,
- ) {
+ override fun SceneScope.Content(modifier: Modifier) {
+
+ val isIdle by remember {
+ derivedStateOf { layoutState.transitionState is TransitionState.Idle }
+ }
+
+ LaunchedEffect(isIdle) {
+ // Wait for being Idle on this Scene, otherwise LaunchedEffect would fire too soon,
+ // and another transition could override the NSSL stack bounds.
+ if (isIdle) {
+ // Reset the stack bounds to avoid caching these values from the previous Scenes,
+ // and not to confuse the StackScrollAlgorithm when it displays a HUN over GONE.
+ notificationStackScrolLView.get().apply {
+ setStackTop(0f)
+ setStackCutoff(0f)
+ }
+ }
+ }
+
animateContentFloatAsState(
value = QuickSettings.SharedValues.SquishinessValues.GoneSceneStarting,
key = QuickSettings.SharedValues.TilesSquishiness,
@@ -75,9 +96,7 @@ constructor(
SnoozeableHeadsUpNotificationSpace(
stackScrollView = notificationStackScrolLView.get(),
viewModel =
- rememberViewModel("GoneScene") {
- notificationsPlaceholderViewModelFactory.create()
- },
+ rememberViewModel("GoneScene") { notificationsPlaceholderViewModelFactory.create() },
)
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index 2d58c8cad2b1..a266e7eb44a1 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -49,7 +49,6 @@ import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
import javax.inject.Provider
-import kotlinx.coroutines.flow.collectLatest
/**
* Renders a container of a collection of "scenes" that the user can switch between using certain
@@ -117,7 +116,7 @@ fun SceneContainer(
) {
"invalid ContentKey: $actionableContentKey"
}
- actionableContent.userActions.collectLatest { userActions ->
+ viewModel.filteredUserActions(actionableContent.userActions).collect { userActions ->
userActionsByContentKey[actionableContentKey] =
viewModel.resolveSceneFamilies(userActions)
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
index 05a0119d68e4..bfcde7dab6d2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
@@ -130,10 +130,6 @@ fun SceneScope.CollapsedShadeHeader(
modifier: Modifier = Modifier,
) {
val viewModel = rememberViewModel("CollapsedShadeHeader") { viewModelFactory.create() }
- val isDisabled by viewModel.isDisabled.collectAsStateWithLifecycle()
- if (isDisabled) {
- return
- }
val cutoutWidth = LocalDisplayCutout.current.width()
val cutoutHeight = LocalDisplayCutout.current.height()
@@ -196,7 +192,7 @@ fun SceneScope.CollapsedShadeHeader(
horizontalArrangement = Arrangement.End,
modifier =
Modifier.element(ShadeHeader.Elements.CollapsedContentEnd)
- .padding(horizontal = horizontalPadding)
+ .padding(horizontal = horizontalPadding),
) {
if (isLargeScreenLayout) {
ShadeCarrierGroup(
@@ -207,7 +203,7 @@ fun SceneScope.CollapsedShadeHeader(
SystemIconContainer(
viewModel = viewModel,
isClickable = isLargeScreenLayout,
- modifier = Modifier.align(Alignment.CenterVertically)
+ modifier = Modifier.align(Alignment.CenterVertically),
) {
StatusIcons(
viewModel = viewModel,
@@ -217,7 +213,7 @@ fun SceneScope.CollapsedShadeHeader(
modifier =
Modifier.align(Alignment.CenterVertically)
.padding(end = 6.dp)
- .weight(1f, fill = false)
+ .weight(1f, fill = false),
)
BatteryIcon(
createBatteryMeterViewController =
@@ -252,27 +248,15 @@ fun SceneScope.CollapsedShadeHeader(
CutoutLocation.NONE,
CutoutLocation.RIGHT -> {
startPlaceable.placeRelative(x = 0, y = 0)
- endPlaceable.placeRelative(
- x = startPlaceable.width,
- y = 0,
- )
+ endPlaceable.placeRelative(x = startPlaceable.width, y = 0)
}
CutoutLocation.CENTER -> {
startPlaceable.placeRelative(x = 0, y = 0)
- endPlaceable.placeRelative(
- x = startPlaceable.width + cutoutWidthPx,
- y = 0,
- )
+ endPlaceable.placeRelative(x = startPlaceable.width + cutoutWidthPx, y = 0)
}
CutoutLocation.LEFT -> {
- startPlaceable.placeRelative(
- x = cutoutWidthPx,
- y = 0,
- )
- endPlaceable.placeRelative(
- x = startPlaceable.width + cutoutWidthPx,
- y = 0,
- )
+ startPlaceable.placeRelative(x = cutoutWidthPx, y = 0)
+ endPlaceable.placeRelative(x = startPlaceable.width + cutoutWidthPx, y = 0)
}
}
}
@@ -288,10 +272,6 @@ fun SceneScope.ExpandedShadeHeader(
modifier: Modifier = Modifier,
) {
val viewModel = rememberViewModel("ExpandedShadeHeader") { viewModelFactory.create() }
- val isDisabled by viewModel.isDisabled.collectAsStateWithLifecycle()
- if (isDisabled) {
- return
- }
val useExpandedFormat by remember {
derivedStateOf { shouldUseExpandedFormat(layoutState.transitionState) }
@@ -302,17 +282,14 @@ fun SceneScope.ExpandedShadeHeader(
Box(modifier = modifier.sysuiResTag(ShadeHeader.TestTags.Root)) {
if (isPrivacyChipVisible) {
Box(modifier = Modifier.height(CollapsedHeight).fillMaxWidth()) {
- PrivacyChip(
- viewModel = viewModel,
- modifier = Modifier.align(Alignment.CenterEnd),
- )
+ PrivacyChip(viewModel = viewModel, modifier = Modifier.align(Alignment.CenterEnd))
}
}
Column(
verticalArrangement = Arrangement.Bottom,
modifier =
Modifier.fillMaxWidth()
- .defaultMinSize(minHeight = ShadeHeader.Dimensions.ExpandedHeight)
+ .defaultMinSize(minHeight = ShadeHeader.Dimensions.ExpandedHeight),
) {
Box(modifier = Modifier.fillMaxWidth()) {
Box {
@@ -362,11 +339,7 @@ fun SceneScope.ExpandedShadeHeader(
}
@Composable
-private fun SceneScope.Clock(
- scale: Float,
- viewModel: ShadeHeaderViewModel,
- modifier: Modifier,
-) {
+private fun SceneScope.Clock(scale: Float, viewModel: ShadeHeaderViewModel, modifier: Modifier) {
val layoutDirection = LocalLayoutDirection.current
Element(key = ShadeHeader.Elements.Clock, modifier = modifier) {
@@ -391,10 +364,10 @@ private fun SceneScope.Clock(
LayoutDirection.Ltr -> 0f
LayoutDirection.Rtl -> 1f
},
- 0.5f
+ 0.5f,
)
}
- .clickable { viewModel.onClockClicked() }
+ .clickable { viewModel.onClockClicked() },
)
}
}
@@ -447,10 +420,7 @@ private fun BatteryIcon(
}
@Composable
-private fun ShadeCarrierGroup(
- viewModel: ShadeHeaderViewModel,
- modifier: Modifier = Modifier,
-) {
+private fun ShadeCarrierGroup(viewModel: ShadeHeaderViewModel, modifier: Modifier = Modifier) {
Row(modifier = modifier) {
val subIds by viewModel.mobileSubIds.collectAsStateWithLifecycle()
@@ -465,11 +435,11 @@ private fun ShadeCarrierGroup(
viewModel =
(viewModel.mobileIconsViewModel.viewModelForSub(
subId,
- StatusBarLocation.SHADE_CARRIER_GROUP
+ StatusBarLocation.SHADE_CARRIER_GROUP,
) as ShadeCarrierGroupMobileIconViewModel),
)
.also { it.setOnClickListener { viewModel.onShadeCarrierGroupClicked() } }
- },
+ }
)
}
}
@@ -506,7 +476,7 @@ private fun SceneScope.StatusIcons(
Utils.getColorAttrDefaultColor(themedContext, android.R.attr.textColorPrimary),
Utils.getColorAttrDefaultColor(
themedContext,
- android.R.attr.textColorPrimaryInverse
+ android.R.attr.textColorPrimaryInverse,
),
)
statusBarIconController.addIconGroup(iconManager)
@@ -551,7 +521,7 @@ private fun SystemIconContainer(
viewModel: ShadeHeaderViewModel,
isClickable: Boolean,
modifier: Modifier = Modifier,
- content: @Composable RowScope.() -> Unit
+ content: @Composable RowScope.() -> Unit,
) {
val interactionSource = remember { MutableInteractionSource() }
val isHovered by interactionSource.collectIsHoveredAsState()
@@ -578,10 +548,7 @@ private fun SystemIconContainer(
}
@Composable
-private fun SceneScope.PrivacyChip(
- viewModel: ShadeHeaderViewModel,
- modifier: Modifier = Modifier,
-) {
+private fun SceneScope.PrivacyChip(viewModel: ShadeHeaderViewModel, modifier: Modifier = Modifier) {
val privacyList by viewModel.privacyItems.collectAsStateWithLifecycle()
AndroidView(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index bba3d69ea77f..fd1632ed4cb4 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -353,13 +353,24 @@ private fun SceneScope.SingleShade(
)
}
+ val qqsLayoutPaddingBottom =
+ dimensionResource(id = R.dimen.qqs_layout_padding_bottom)
ShadeMediaCarousel(
isVisible = isMediaVisible,
isInRow = mediaInRow,
mediaHost = mediaHost,
mediaOffsetProvider = mediaOffsetProvider,
carouselController = mediaCarouselController,
- modifier = Modifier.layoutId(SingleShadeMeasurePolicy.LayoutId.Media),
+ modifier =
+ Modifier.layoutId(SingleShadeMeasurePolicy.LayoutId.Media)
+ .padding(
+ horizontal =
+ shadeHorizontalPadding +
+ dimensionResource(id = R.dimen.qs_horizontal_margin)
+ )
+ .thenIf(!mediaInRow) {
+ Modifier.padding(bottom = qqsLayoutPaddingBottom)
+ },
usingCollapsedLandscapeMedia = usingCollapsedLandscapeMedia,
isInSplitShade = false,
)
@@ -562,10 +573,14 @@ private fun SceneScope.SplitShade(
mediaOffsetProvider = mediaOffsetProvider,
modifier =
Modifier.thenIf(
- MediaContentPicker.shouldElevateMedia(layoutState)
- ) {
- Modifier.zIndex(1f)
- },
+ MediaContentPicker.shouldElevateMedia(layoutState)
+ ) {
+ Modifier.zIndex(1f)
+ }
+ .padding(
+ horizontal =
+ dimensionResource(id = R.dimen.qs_horizontal_margin)
+ ),
carouselController = mediaCarouselController,
isInSplitShade = true,
)
diff --git a/packages/SystemUI/customization/res/values/dimens.xml b/packages/SystemUI/customization/res/values/dimens.xml
index 21b4c7165226..2bb5541f4b0a 100644
--- a/packages/SystemUI/customization/res/values/dimens.xml
+++ b/packages/SystemUI/customization/res/values/dimens.xml
@@ -33,6 +33,7 @@
<dimen name="small_clock_height">114dp</dimen>
<dimen name="small_clock_padding_top">28dp</dimen>
<dimen name="clock_padding_start">28dp</dimen>
+ <dimen name="weather_date_icon_padding">28dp</dimen>
<!-- When large clock is showing, offset the smartspace by this amount -->
<dimen name="keyguard_smartspace_top_offset">12dp</dimen>
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
index 0f148f89e3c5..2d093bf1630b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
@@ -25,6 +25,7 @@ import com.android.systemui.brightness.domain.interactor.brightnessPolicyEnforce
import com.android.systemui.brightness.domain.interactor.screenBrightnessInteractor
import com.android.systemui.brightness.shared.model.GammaBrightness
import com.android.systemui.brightness.shared.model.LinearBrightness
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
@@ -61,6 +62,7 @@ class BrightnessSliderViewModelTest : SysuiTestCase() {
brightnessPolicyEnforcementInteractor,
sliderHapticsViewModelFactory,
brightnessMirrorShowingInteractor,
+ falsingInteractor,
supportsMirroring = true,
brightnessWarningToast,
)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index d90d58b8d25c..1bb5c9afdc33 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -43,7 +43,6 @@ import com.android.systemui.keyguard.data.repository.fakeTrustRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.domain.interactor.sceneBackInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.domain.startable.sceneContainerStartable
import com.android.systemui.scene.shared.model.Scenes
@@ -72,7 +71,6 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
private val trustRepository by lazy { kosmos.fakeTrustRepository }
private val sceneInteractor by lazy { kosmos.sceneInteractor }
private val authenticationInteractor by lazy { kosmos.authenticationInteractor }
- private val sceneBackInteractor by lazy { kosmos.sceneBackInteractor }
private val sceneContainerStartable by lazy { kosmos.sceneContainerStartable }
private val sysuiStatusBarStateController by lazy { kosmos.sysuiStatusBarStateController }
private lateinit var underTest: DeviceEntryInteractor
@@ -437,7 +435,9 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
fun isDeviceEntered_unlockedWhileOnShade_emitsTrue() =
testScope.runTest {
val isDeviceEntered by collectLastValue(underTest.isDeviceEntered)
+ val isDeviceEnteredDirectly by collectLastValue(underTest.isDeviceEnteredDirectly)
assertThat(isDeviceEntered).isFalse()
+ assertThat(isDeviceEnteredDirectly).isFalse()
val currentScene by collectLastValue(sceneInteractor.currentScene)
assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
@@ -445,19 +445,20 @@ class DeviceEntryInteractorTest : SysuiTestCase() {
switchToScene(Scenes.Shade)
assertThat(currentScene).isEqualTo(Scenes.Shade)
// Simulating a "leave it open when the keyguard is hidden" which means the bouncer will
- // be
- // shown and successful authentication should take the user back to where they are, the
- // shade scene.
+ // be shown and successful authentication should take the user back to where they are,
+ // the shade scene.
sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true)
switchToScene(Scenes.Bouncer)
assertThat(currentScene).isEqualTo(Scenes.Bouncer)
assertThat(isDeviceEntered).isFalse()
+ assertThat(isDeviceEnteredDirectly).isFalse()
// Authenticate with PIN to unlock and dismiss the lockscreen:
authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
runCurrent()
assertThat(isDeviceEntered).isTrue()
+ assertThat(isDeviceEnteredDirectly).isFalse()
}
private fun TestScope.switchToScene(sceneKey: SceneKey) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index bbfc9607fed9..a8048793be06 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -36,7 +36,6 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.test.filters.SmallTest
-import com.android.app.viewcapture.ViewCapture
import com.android.app.viewcapture.ViewCaptureAwareWindowManager
import com.android.app.viewcapture.ViewCaptureFactory
import com.android.compose.animation.scene.ObservableTransitionState
@@ -44,15 +43,15 @@ import com.android.internal.logging.UiEventLogger
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
+import com.android.systemui.Flags.FLAG_COMMUNAL_HUB_ON_MOBILE
import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
import com.android.systemui.SysuiTestCase
+import com.android.systemui.ambient.touch.TouchHandler
import com.android.systemui.ambient.touch.TouchMonitor
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
import com.android.systemui.ambient.touch.scrim.ScrimController
import com.android.systemui.ambient.touch.scrim.ScrimManager
-import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
-import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.communalInteractor
@@ -64,6 +63,7 @@ import com.android.systemui.complication.ComplicationLayoutEngine
import com.android.systemui.complication.dagger.ComplicationComponent
import com.android.systemui.dreams.complication.HideComplicationTouchHandler
import com.android.systemui.dreams.dagger.DreamOverlayComponent
+import com.android.systemui.dreams.touch.CommunalTouchHandler
import com.android.systemui.flags.andSceneContainer
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.gesture.domain.gestureInteractor
@@ -87,21 +87,17 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
-import org.mockito.Captor
-import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.isNull
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.eq
import org.mockito.kotlin.firstValue
import org.mockito.kotlin.mock
import org.mockito.kotlin.spy
-import org.mockito.kotlin.times
import org.mockito.kotlin.verifyNoMoreInteractions
import org.mockito.kotlin.whenever
import platform.test.runner.parameterized.ParameterizedAndroidJunit4
@@ -117,68 +113,50 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
private val kosmos = testKosmos()
private val testScope = kosmos.testScope
- @Mock lateinit var mLifecycleOwner: DreamOverlayLifecycleOwner
-
- private lateinit var lifecycleRegistry: FakeLifecycleRegistry
-
- lateinit var mCommunalInteractor: CommunalInteractor
-
- private lateinit var mWindowParams: WindowManager.LayoutParams
-
- @Mock lateinit var mDreamOverlayCallback: IDreamOverlayCallback
-
- @Mock lateinit var mWindowManager: WindowManagerImpl
-
- @Mock lateinit var mComplicationComponentFactory: ComplicationComponent.Factory
-
- @Mock lateinit var mComplicationHostViewController: ComplicationHostViewController
-
- @Mock lateinit var mComplicationVisibilityController: ComplicationLayoutEngine
-
- @Mock
- lateinit var mDreamComplicationComponentFactory:
- com.android.systemui.dreams.complication.dagger.ComplicationComponent.Factory
-
- @Mock lateinit var mHideComplicationTouchHandler: HideComplicationTouchHandler
-
- @Mock lateinit var mDreamOverlayComponentFactory: DreamOverlayComponent.Factory
-
- @Mock lateinit var mAmbientTouchComponentFactory: AmbientTouchComponent.Factory
-
- @Mock lateinit var mDreamOverlayContainerView: DreamOverlayContainerView
-
- @Mock lateinit var mDreamOverlayContainerViewController: DreamOverlayContainerViewController
-
- @Mock lateinit var mKeyguardUpdateMonitor: KeyguardUpdateMonitor
-
- @Mock lateinit var mTouchMonitor: TouchMonitor
-
- @Mock lateinit var mStateController: DreamOverlayStateController
-
- @Mock lateinit var mDreamOverlayContainerViewParent: ViewGroup
-
- @Mock lateinit var mTouchInsetManager: TouchInsetManager
-
- @Mock lateinit var mUiEventLogger: UiEventLogger
-
- @Mock lateinit var mScrimManager: ScrimManager
-
- @Mock lateinit var mScrimController: ScrimController
-
- @Mock lateinit var mSystemDialogsCloser: SystemDialogsCloser
-
- @Mock lateinit var mDreamOverlayCallbackController: DreamOverlayCallbackController
-
- @Mock lateinit var mLazyViewCapture: Lazy<ViewCapture>
+ private val mLifecycleOwner = mock<DreamOverlayLifecycleOwner>()
+ private val mDreamOverlayCallback = mock<IDreamOverlayCallback>()
+ private val mWindowManager = mock<WindowManagerImpl>()
+ private val mComplicationComponentFactory = mock<ComplicationComponent.Factory>()
+ private val mComplicationHostViewController = mock<ComplicationHostViewController>()
+ private val mComplicationVisibilityController = mock<ComplicationLayoutEngine>()
+ private val mDreamComplicationComponentFactory =
+ mock<com.android.systemui.dreams.complication.dagger.ComplicationComponent.Factory>()
+ private val mHideComplicationTouchHandler = mock<HideComplicationTouchHandler>()
+ private val mDreamOverlayComponentFactory = mock<DreamOverlayComponent.Factory>()
+ private val mCommunalTouchHandler = mock<CommunalTouchHandler>()
+ private val mAmbientTouchComponentFactory = mock<AmbientTouchComponent.Factory>()
+ private val mDreamOverlayContainerView = mock<DreamOverlayContainerView>()
+ private val mDreamOverlayContainerViewController =
+ mock<DreamOverlayContainerViewController> {
+ on { containerView }.thenReturn(mDreamOverlayContainerView)
+ }
+ private val mKeyguardUpdateMonitor = mock<KeyguardUpdateMonitor>()
+ private val mTouchMonitor = mock<TouchMonitor>()
+ private val mStateController = mock<DreamOverlayStateController>()
+ private val mDreamOverlayContainerViewParent = mock<ViewGroup>()
+ private val mTouchInsetManager = mock<TouchInsetManager>()
+ private val mUiEventLogger = mock<UiEventLogger>()
+ private val mScrimController = mock<ScrimController>()
+ private val mScrimManager =
+ mock<ScrimManager> { on { currentController }.thenReturn(mScrimController) }
+ private val mSystemDialogsCloser = mock<SystemDialogsCloser>()
+ private val mDreamOverlayCallbackController = mock<DreamOverlayCallbackController>()
+ private val mLazyViewCapture = lazy { viewCaptureSpy }
+
+ private val mViewCaptor = argumentCaptor<View>()
+ private val mTouchHandlersCaptor = argumentCaptor<Set<TouchHandler>>()
+
+ private val mWindowParams = WindowManager.LayoutParams()
+ private val lifecycleRegistry = FakeLifecycleRegistry(mLifecycleOwner)
+ private val bouncerRepository = kosmos.fakeKeyguardBouncerRepository
+ private val communalRepository = kosmos.fakeCommunalSceneRepository
+ private var viewCaptureSpy = spy(ViewCaptureFactory.getInstance(context))
+ private val gestureInteractor = spy(kosmos.gestureInteractor)
+ private lateinit var mCommunalInteractor: CommunalInteractor
private lateinit var mViewCaptureAwareWindowManager: ViewCaptureAwareWindowManager
- private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
- private lateinit var communalRepository: FakeCommunalSceneRepository
- private var viewCaptureSpy = spy(ViewCaptureFactory.getInstance(context))
- private lateinit var gestureInteractor: GestureInteractor
private lateinit var environmentComponents: EnvironmentComponents
- @Captor var mViewCaptor: ArgumentCaptor<View>? = null
private lateinit var mService: DreamOverlayService
private class EnvironmentComponents(
@@ -234,6 +212,7 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
mock<com.android.systemui.dreams.complication.dagger.ComplicationComponent>()
whenever(dreamComplicationComponent.getHideComplicationTouchHandler())
.thenReturn(mHideComplicationTouchHandler)
+ whenever(dreamOverlayComponent.communalTouchHandler).thenReturn(mCommunalTouchHandler)
whenever(dreamComplicationComponentFactory.create(any(), any()))
.thenReturn(dreamComplicationComponent)
@@ -259,13 +238,6 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
@Before
fun setup() {
- MockitoAnnotations.initMocks(this)
-
- lifecycleRegistry = FakeLifecycleRegistry(mLifecycleOwner)
- bouncerRepository = kosmos.fakeKeyguardBouncerRepository
- communalRepository = kosmos.fakeCommunalSceneRepository
- gestureInteractor = spy(kosmos.gestureInteractor)
-
environmentComponents =
setupComponentFactories(
mDreamComplicationComponentFactory,
@@ -273,12 +245,6 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
mComplicationComponentFactory,
mAmbientTouchComponentFactory,
)
-
- whenever(mDreamOverlayContainerViewController.containerView)
- .thenReturn(mDreamOverlayContainerView)
- whenever(mScrimManager.getCurrentController()).thenReturn(mScrimController)
- whenever(mLazyViewCapture.value).thenReturn(viewCaptureSpy)
- mWindowParams = WindowManager.LayoutParams()
mViewCaptureAwareWindowManager =
ViewCaptureAwareWindowManager(
mWindowManager,
@@ -381,10 +347,10 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
verify(mStateController).setOverlayActive(false)
verify(mStateController).setLowLightActive(false)
verify(mStateController).setEntryAnimationsFinished(false)
- verify(mStateController, Mockito.never()).setOverlayActive(true)
- verify(mUiEventLogger, Mockito.never())
+ verify(mStateController, never()).setOverlayActive(true)
+ verify(mUiEventLogger, never())
.log(DreamOverlayService.DreamOverlayEvent.DREAM_OVERLAY_COMPLETE_START)
- verify(mDreamOverlayCallbackController, Mockito.never()).onStartDream()
+ verify(mDreamOverlayCallbackController, never()).onStartDream()
}
@Test
@@ -528,14 +494,14 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
mMainExecutor.runAllReady()
// Verify view added.
- verify(mWindowManager).addView(mViewCaptor!!.capture(), any())
+ verify(mWindowManager).addView(mViewCaptor.capture(), any())
// Service destroyed.
mService.onEndDream()
mMainExecutor.runAllReady()
// Verify view removed.
- verify(mWindowManager).removeView(mViewCaptor!!.value)
+ verify(mWindowManager).removeView(mViewCaptor.firstValue)
// Verify state correctly set.
verify(mStateController).setOverlayActive(false)
@@ -567,8 +533,8 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
// The overlay starts then finishes.
val inOrder = Mockito.inOrder(mWindowManager)
- inOrder.verify(mWindowManager).addView(mViewCaptor!!.capture(), any())
- inOrder.verify(mWindowManager).removeView(mViewCaptor!!.value)
+ inOrder.verify(mWindowManager).addView(mViewCaptor.capture(), any())
+ inOrder.verify(mWindowManager).removeView(mViewCaptor.firstValue)
}
@Test
@@ -596,8 +562,8 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
// The overlay starts then finishes.
val inOrder = Mockito.inOrder(mWindowManager)
- inOrder.verify(mWindowManager).addView(mViewCaptor!!.capture(), any())
- inOrder.verify(mWindowManager).removeView(mViewCaptor!!.value)
+ inOrder.verify(mWindowManager).addView(mViewCaptor.capture(), any())
+ inOrder.verify(mWindowManager).removeView(mViewCaptor.firstValue)
}
@Test
@@ -615,14 +581,14 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
mMainExecutor.runAllReady()
// Verify view added.
- verify(mWindowManager).addView(mViewCaptor!!.capture(), any())
+ verify(mWindowManager).addView(mViewCaptor.capture(), any())
// Service destroyed.
mService.onDestroy()
mMainExecutor.runAllReady()
// Verify view removed.
- verify(mWindowManager).removeView(mViewCaptor!!.value)
+ verify(mWindowManager).removeView(mViewCaptor.firstValue)
// Verify state correctly set.
verify(mKeyguardUpdateMonitor).removeCallback(any())
@@ -639,7 +605,7 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
mMainExecutor.runAllReady()
// Verify no view is removed.
- verify(mWindowManager, Mockito.never()).removeView(any())
+ verify(mWindowManager, never()).removeView(any())
// Verify state still correctly set.
verify(mKeyguardUpdateMonitor).removeCallback(any())
@@ -665,7 +631,7 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
false, /*shouldShowComplication*/
)
mMainExecutor.runAllReady()
- verify(mWindowManager, Mockito.never()).addView(any(), any())
+ verify(mWindowManager, never()).addView(any(), any())
}
@Test
@@ -673,7 +639,7 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
// Service destroyed before dream started.
mService.onDestroy()
mMainExecutor.runAllReady()
- verify(mWindowManager, Mockito.never()).removeView(any())
+ verify(mWindowManager, never()).removeView(any())
}
@Test
@@ -691,8 +657,8 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
mMainExecutor.runAllReady()
// Verify that a new window is added.
- verify(mWindowManager).addView(mViewCaptor!!.capture(), any())
- val windowDecorView = mViewCaptor!!.value
+ verify(mWindowManager).addView(mViewCaptor.capture(), any())
+ val windowDecorView = mViewCaptor.firstValue
// Assert that the overlay is not showing complications.
assertThat(mService.shouldShowComplications()).isFalse()
@@ -751,7 +717,7 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
@Test
fun testWakeUpBeforeStartDoesNothing() {
mService.onWakeUp()
- verify(mDreamOverlayContainerViewController, Mockito.never()).onWakeUp()
+ verify(mDreamOverlayContainerViewController, never()).onWakeUp()
}
@Test
@@ -879,8 +845,8 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
)
mMainExecutor.runAllReady()
- whenever(mDreamOverlayContainerViewController.isBouncerShowing()).thenReturn(true)
- mService!!.onComeToFront()
+ whenever(mDreamOverlayContainerViewController.isBouncerShowing).thenReturn(true)
+ mService.onComeToFront()
verify(mScrimController).expand(any())
}
@@ -900,7 +866,7 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
)
mMainExecutor.runAllReady()
- mService!!.onComeToFront()
+ mService.onComeToFront()
assertThat(communalRepository.currentScene.value).isEqualTo(CommunalScenes.Blank)
}
@@ -920,7 +886,7 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
)
mMainExecutor.runAllReady()
- mService!!.onComeToFront()
+ mService.onComeToFront()
verify(mSystemDialogsCloser).closeSystemDialogs()
}
@@ -1320,6 +1286,45 @@ class DreamOverlayServiceTest(flags: FlagsParameterization?) : SysuiTestCase() {
environmentComponents.verifyNoMoreInteractions()
}
+ @DisableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @Test
+ fun testAmbientTouchHandlersRegistration_registerHideComplicationAndCommunal() {
+ val client = client
+
+ // Inform the overlay service of dream starting.
+ client.startDream(
+ mWindowParams,
+ mDreamOverlayCallback,
+ DREAM_COMPONENT,
+ false /*isPreview*/,
+ false, /*shouldShowComplication*/
+ )
+ mMainExecutor.runAllReady()
+
+ verify(mAmbientTouchComponentFactory).create(any(), mTouchHandlersCaptor.capture(), any())
+ assertThat(mTouchHandlersCaptor.firstValue)
+ .containsExactly(mHideComplicationTouchHandler, mCommunalTouchHandler)
+ }
+
+ @EnableFlags(FLAG_COMMUNAL_HUB_ON_MOBILE)
+ @Test
+ fun testAmbientTouchHandlersRegistration_v2_registerOnlyHideComplication() {
+ val client = client
+
+ // Inform the overlay service of dream starting.
+ client.startDream(
+ mWindowParams,
+ mDreamOverlayCallback,
+ DREAM_COMPONENT,
+ false /*isPreview*/,
+ false, /*shouldShowComplication*/
+ )
+ mMainExecutor.runAllReady()
+
+ verify(mAmbientTouchComponentFactory).create(any(), mTouchHandlersCaptor.capture(), any())
+ assertThat(mTouchHandlersCaptor.firstValue).containsExactly(mHideComplicationTouchHandler)
+ }
+
internal class FakeLifecycleRegistry(provider: LifecycleOwner) : LifecycleRegistry(provider) {
val mLifecycles: MutableList<State> = ArrayList()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
index 82bcecef1f70..55b87db232e8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelTest.kt
@@ -27,6 +27,7 @@ import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.flags.EnableSceneContainer
@@ -72,8 +73,10 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
@Test
@DisableFlags(DualShade.FLAG_NAME)
- fun actions_singleShade() =
+ fun actions_communalNotAvailable_singleShade() =
testScope.runTest {
+ kosmos.setCommunalAvailable(false)
+
val actions by collectLastValue(underTest.actions)
setUpState(
@@ -85,6 +88,8 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true))
+ assertThat(actions?.get(Swipe.Start)).isNull()
+ assertThat(actions?.get(Swipe.End)).isNull()
setUpState(
isShadeTouchable = false,
@@ -102,12 +107,16 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true))
+ assertThat(actions?.get(Swipe.Start)).isNull()
+ assertThat(actions?.get(Swipe.End)).isNull()
}
@Test
@DisableFlags(DualShade.FLAG_NAME)
- fun actions_splitShade() =
+ fun actions_communalNotAvailable_splitShade() =
testScope.runTest {
+ kosmos.setCommunalAvailable(false)
+
val actions by collectLastValue(underTest.actions)
setUpState(
@@ -119,6 +128,8 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true))
+ assertThat(actions?.get(Swipe.Start)).isNull()
+ assertThat(actions?.get(Swipe.End)).isNull()
setUpState(
isShadeTouchable = false,
@@ -136,12 +147,136 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
assertThat(actions?.get(Swipe.Down))
.isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true))
+ assertThat(actions?.get(Swipe.Start)).isNull()
+ assertThat(actions?.get(Swipe.End)).isNull()
}
@Test
@EnableFlags(DualShade.FLAG_NAME)
- fun actions_dualShade() =
+ fun actions_communalNotAvailable_dualShade() =
testScope.runTest {
+ kosmos.setCommunalAvailable(false)
+
+ val actions by collectLastValue(underTest.actions)
+
+ setUpState(
+ isShadeTouchable = true,
+ isDeviceUnlocked = false,
+ shadeMode = ShadeMode.Dual,
+ )
+ assertThat(actions).isNotEmpty()
+ assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+ assertThat(actions?.get(Swipe.Down))
+ .isEqualTo(
+ UserActionResult.ShowOverlay(Overlays.NotificationsShade, isIrreversible = true)
+ )
+ assertThat(actions?.get(Swipe.Start)).isNull()
+ assertThat(actions?.get(Swipe.End)).isNull()
+
+ setUpState(
+ isShadeTouchable = false,
+ isDeviceUnlocked = false,
+ shadeMode = ShadeMode.Dual,
+ )
+ assertThat(actions).isEmpty()
+
+ setUpState(isShadeTouchable = true, isDeviceUnlocked = true, shadeMode = ShadeMode.Dual)
+ assertThat(actions).isNotEmpty()
+ assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
+ assertThat(actions?.get(Swipe.Down))
+ .isEqualTo(
+ UserActionResult.ShowOverlay(Overlays.NotificationsShade, isIrreversible = true)
+ )
+ assertThat(actions?.get(Swipe.Start)).isNull()
+ assertThat(actions?.get(Swipe.End)).isNull()
+ }
+
+ @Test
+ @DisableFlags(DualShade.FLAG_NAME)
+ fun actions_communalAvailable_singleShade() =
+ testScope.runTest {
+ kosmos.setCommunalAvailable(true)
+
+ val actions by collectLastValue(underTest.actions)
+
+ setUpState(
+ isShadeTouchable = true,
+ isDeviceUnlocked = false,
+ shadeMode = ShadeMode.Single,
+ )
+ assertThat(actions).isNotEmpty()
+ assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+ assertThat(actions?.get(Swipe.Down))
+ .isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true))
+ assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+ assertThat(actions?.get(Swipe.End)).isNull()
+
+ setUpState(
+ isShadeTouchable = false,
+ isDeviceUnlocked = false,
+ shadeMode = ShadeMode.Single,
+ )
+ assertThat(actions).isEmpty()
+
+ setUpState(
+ isShadeTouchable = true,
+ isDeviceUnlocked = true,
+ shadeMode = ShadeMode.Single,
+ )
+ assertThat(actions).isNotEmpty()
+ assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
+ assertThat(actions?.get(Swipe.Down))
+ .isEqualTo(UserActionResult(Scenes.Shade, isIrreversible = true))
+ assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+ assertThat(actions?.get(Swipe.End)).isNull()
+ }
+
+ @Test
+ @DisableFlags(DualShade.FLAG_NAME)
+ fun actions_communalAvailable_splitShade() =
+ testScope.runTest {
+ kosmos.setCommunalAvailable(true)
+
+ val actions by collectLastValue(underTest.actions)
+
+ setUpState(
+ isShadeTouchable = true,
+ isDeviceUnlocked = false,
+ shadeMode = ShadeMode.Split,
+ )
+ assertThat(actions).isNotEmpty()
+ assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Bouncer))
+ assertThat(actions?.get(Swipe.Down))
+ .isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true))
+ assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+ assertThat(actions?.get(Swipe.End)).isNull()
+
+ setUpState(
+ isShadeTouchable = false,
+ isDeviceUnlocked = false,
+ shadeMode = ShadeMode.Split,
+ )
+ assertThat(actions).isEmpty()
+
+ setUpState(
+ isShadeTouchable = true,
+ isDeviceUnlocked = true,
+ shadeMode = ShadeMode.Split,
+ )
+ assertThat(actions).isNotEmpty()
+ assertThat(actions?.get(Swipe.Up)).isEqualTo(UserActionResult(Scenes.Gone))
+ assertThat(actions?.get(Swipe.Down))
+ .isEqualTo(UserActionResult(Scenes.Shade, ToSplitShade, isIrreversible = true))
+ assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+ assertThat(actions?.get(Swipe.End)).isNull()
+ }
+
+ @Test
+ @EnableFlags(DualShade.FLAG_NAME)
+ fun actions_communalAvailable_dualShade() =
+ testScope.runTest {
+ kosmos.setCommunalAvailable(true)
+
val actions by collectLastValue(underTest.actions)
setUpState(
@@ -155,6 +290,8 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
.isEqualTo(
UserActionResult.ShowOverlay(Overlays.NotificationsShade, isIrreversible = true)
)
+ assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+ assertThat(actions?.get(Swipe.End)).isNull()
setUpState(
isShadeTouchable = false,
@@ -170,6 +307,8 @@ class DreamUserActionsViewModelTest : SysuiTestCase() {
.isEqualTo(
UserActionResult.ShowOverlay(Overlays.NotificationsShade, isIrreversible = true)
)
+ assertThat(actions?.get(Swipe.Start)).isEqualTo(UserActionResult(Scenes.Communal))
+ assertThat(actions?.get(Swipe.End)).isNull()
}
private fun TestScope.setUpState(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
index 639737b37efd..76434ee54627 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModelTest.kt
@@ -27,9 +27,11 @@ import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger
import com.android.systemui.inputdevice.tutorial.domain.interactor.KeyboardTouchpadConnectionInteractor
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEY
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEYBOARD
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEY
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME
import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.ACTION_KEY
import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.BACK_GESTURE
import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.HOME_GESTURE
@@ -66,8 +68,8 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
private val sysUiState = kosmos.sysUiState
private val touchpadRepo = PrettyFakeTouchpadRepository()
private val keyboardRepo = kosmos.keyboardRepository
- private var startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD
- private val viewModel by lazy { createViewModel(startingPeripheral) }
+ private var tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
+ private val viewModel by lazy { createViewModel(tutorialScope) }
// createUnsafe so its methods don't have to be called on Main thread
private val lifecycle = LifecycleRegistry.createUnsafe(mock(LifecycleOwner::class.java))
@@ -75,7 +77,7 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
@get:Rule val mainDispatcherRule = MainDispatcherRule(kosmos.testDispatcher)
private fun createViewModel(
- startingPeripheral: String = INTENT_TUTORIAL_TYPE_TOUCHPAD,
+ scope: String = INTENT_TUTORIAL_SCOPE_TOUCHPAD,
hasTouchpadTutorialScreens: Boolean = true,
): KeyboardTouchpadTutorialViewModel {
val viewModel =
@@ -84,7 +86,7 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
KeyboardTouchpadConnectionInteractor(keyboardRepo, touchpadRepo),
hasTouchpadTutorialScreens,
mock<InputDeviceTutorialLogger>(),
- SavedStateHandle(mapOf(INTENT_TUTORIAL_TYPE_KEY to startingPeripheral))
+ SavedStateHandle(mapOf(INTENT_TUTORIAL_SCOPE_KEY to scope)),
)
lifecycle.addObserver(viewModel)
return viewModel
@@ -169,7 +171,7 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
@Test
fun screensOrder_whenGoingBackAndOnlyKeyboardConnected() =
testScope.runTest {
- startingPeripheral = INTENT_TUTORIAL_TYPE_KEYBOARD
+ tutorialScope = INTENT_TUTORIAL_SCOPE_KEYBOARD
val screens by collectValues(viewModel.screen)
val closeActivity by collectLastValue(viewModel.closeActivity)
peripheralsState(keyboardConnected = true, touchpadConnected = false)
@@ -185,7 +187,7 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
@Test
fun screensOrder_whenTouchpadConnected() =
testScope.runTest {
- startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD
+ tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
val screens by collectValues(viewModel.screen)
val closeActivity by collectLastValue(viewModel.closeActivity)
@@ -193,22 +195,47 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
goToNextScreen()
goToNextScreen()
- goToNextScreen()
assertThat(screens).containsExactly(BACK_GESTURE, HOME_GESTURE).inOrder()
assertThat(closeActivity).isTrue()
}
@Test
- fun screensOrder_whenKeyboardConnected() =
+ fun screensOrder_withBackGestureScope() =
testScope.runTest {
- startingPeripheral = INTENT_TUTORIAL_TYPE_KEYBOARD
+ tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK
val screens by collectValues(viewModel.screen)
val closeActivity by collectLastValue(viewModel.closeActivity)
+ peripheralsState(touchpadConnected = true)
- peripheralsState(keyboardConnected = true)
+ goToNextScreen()
+
+ assertThat(screens).containsExactly(BACK_GESTURE).inOrder()
+ assertThat(closeActivity).isTrue()
+ }
+
+ @Test
+ fun screensOrder_withHomeGestureScope() =
+ testScope.runTest {
+ tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME
+ val screens by collectValues(viewModel.screen)
+ val closeActivity by collectLastValue(viewModel.closeActivity)
+ peripheralsState(touchpadConnected = true)
goToNextScreen()
+
+ assertThat(screens).containsExactly(HOME_GESTURE).inOrder()
+ assertThat(closeActivity).isTrue()
+ }
+
+ @Test
+ fun screensOrder_withKeyboardScope() =
+ testScope.runTest {
+ tutorialScope = INTENT_TUTORIAL_SCOPE_KEYBOARD
+ val screens by collectValues(viewModel.screen)
+ val closeActivity by collectLastValue(viewModel.closeActivity)
+ peripheralsState(keyboardConnected = true)
+
goToNextScreen()
assertThat(screens).containsExactly(ACTION_KEY).inOrder()
@@ -218,7 +245,7 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
@Test
fun touchpadGesturesDisabled_onlyDuringTouchpadTutorial() =
testScope.runTest {
- startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD
+ tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
collectValues(viewModel.screen) // just to initialize viewModel
peripheralsState(keyboardConnected = true, touchpadConnected = true)
@@ -234,8 +261,8 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
testScope.runTest {
val viewModel =
createViewModel(
- startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD,
- hasTouchpadTutorialScreens = false
+ scope = INTENT_TUTORIAL_SCOPE_TOUCHPAD,
+ hasTouchpadTutorialScreens = false,
)
val screens by collectValues(viewModel.screen)
val closeActivity by collectLastValue(viewModel.closeActivity)
@@ -248,7 +275,7 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
@Test
fun touchpadGesturesDisabled_whenTutorialGoesToForeground() =
testScope.runTest {
- startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD
+ tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
collectValues(viewModel.screen) // just to initialize viewModel
peripheralsState(touchpadConnected = true)
@@ -260,7 +287,7 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
@Test
fun touchpadGesturesNotDisabled_whenTutorialGoesToBackground() =
testScope.runTest {
- startingPeripheral = INTENT_TUTORIAL_TYPE_TOUCHPAD
+ tutorialScope = INTENT_TUTORIAL_SCOPE_TOUCHPAD
collectValues(viewModel.screen)
peripheralsState(touchpadConnected = true)
@@ -288,7 +315,7 @@ class KeyboardTouchpadTutorialViewModelTest : SysuiTestCase() {
private fun TestScope.peripheralsState(
keyboardConnected: Boolean = false,
- touchpadConnected: Boolean = false
+ touchpadConnected: Boolean = false,
) {
keyboardRepo.setIsAnyKeyboardConnected(keyboardConnected)
touchpadRepo.setIsAnyTouchpadConnected(touchpadConnected)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt
index f04540426fc1..0d32b7fb1b3e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepositoryTest.kt
@@ -18,36 +18,31 @@ package com.android.systemui.keyboard.shortcut.data.repository
import android.content.Context
import android.content.Context.INPUT_SERVICE
-import android.hardware.input.InputGestureData
-import android.hardware.input.InputGestureData.createKeyTrigger
-import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
+import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS
import android.hardware.input.fakeInputManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
-import android.view.KeyEvent.KEYCODE_A
import android.view.KeyEvent.KEYCODE_SLASH
-import android.view.KeyEvent.META_ALT_ON
import android.view.KeyEvent.META_CAPS_LOCK_ON
-import android.view.KeyEvent.META_CTRL_ON
-import android.view.KeyEvent.META_FUNCTION_ON
-import android.view.KeyEvent.META_META_LEFT_ON
import android.view.KeyEvent.META_META_ON
-import android.view.KeyEvent.META_SHIFT_ON
-import android.view.KeyEvent.META_SHIFT_RIGHT_ON
-import android.view.KeyEvent.META_SYM_ON
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.hardware.input.Flags.FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES
import com.android.hardware.input.Flags.FLAG_USE_KEY_GESTURE_EVENT_HANDLER
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyboard.shared.model.ShortcutCustomizationRequestResult
import com.android.systemui.keyboard.shortcut.customShortcutCategoriesRepository
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.ALL_SUPPORTED_MODIFIERS
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allAppsInputGestureData
import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allCustomizableInputGesturesWithSimpleShortcutCombinations
import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.customizableInputGestureWithUnknownKeyGestureType
import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedShortcutCategoriesWithSimpleShortcutCombination
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.goHomeInputGestureData
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardAddCustomShortcutRequestInfo
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardDeleteCustomShortcutRequestInfo
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardKeyCombination
import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
import com.android.systemui.kosmos.testScope
@@ -74,24 +69,21 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
it.userTracker = FakeUserTracker(onCreateCurrentUserContext = { mockUserContext })
}
- private val fakeInputManager = kosmos.fakeInputManager
+ private val inputManager = kosmos.fakeInputManager.inputManager
private val testScope = kosmos.testScope
private val helper = kosmos.shortcutHelperTestHelper
private val repo = kosmos.customShortcutCategoriesRepository
@Before
fun setup() {
- whenever(mockUserContext.getSystemService(INPUT_SERVICE))
- .thenReturn(fakeInputManager.inputManager)
+ whenever(mockUserContext.getSystemService(INPUT_SERVICE)).thenReturn(inputManager)
}
@Test
@EnableFlags(FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES, FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
fun categories_emitsCorrectlyConvertedShortcutCategories() {
testScope.runTest {
- whenever(
- fakeInputManager.inputManager.getCustomInputGestures(/* filter= */ anyOrNull())
- )
+ whenever(inputManager.getCustomInputGestures(/* filter= */ anyOrNull()))
.thenReturn(allCustomizableInputGesturesWithSimpleShortcutCombinations)
helper.toggle(deviceId = 123)
@@ -106,9 +98,7 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
@DisableFlags(FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES, FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
fun categories_emitsEmptyListWhenFlagIsDisabled() {
testScope.runTest {
- whenever(
- fakeInputManager.inputManager.getCustomInputGestures(/* filter= */ anyOrNull())
- )
+ whenever(inputManager.getCustomInputGestures(/* filter= */ anyOrNull()))
.thenReturn(allCustomizableInputGesturesWithSimpleShortcutCombinations)
helper.toggle(deviceId = 123)
@@ -122,9 +112,7 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
@EnableFlags(FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES, FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
fun categories_ignoresUnknownKeyGestureTypes() {
testScope.runTest {
- whenever(
- fakeInputManager.inputManager.getCustomInputGestures(/* filter= */ anyOrNull())
- )
+ whenever(inputManager.getCustomInputGestures(/* filter= */ anyOrNull()))
.thenReturn(customizableInputGestureWithUnknownKeyGestureType)
helper.toggle(deviceId = 123)
@@ -151,7 +139,7 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
helper.toggle(deviceId = 123)
val pressedKeys by collectLastValue(repo.pressedKeys)
repo.updateUserKeyCombination(
- KeyCombination(modifiers = allSupportedModifiers, keyCode = null)
+ KeyCombination(modifiers = ALL_SUPPORTED_MODIFIERS, keyCode = null)
)
assertThat(pressedKeys)
@@ -199,11 +187,11 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
@Test
fun shortcutBeingCustomized_updatedOnCustomizationRequested() {
testScope.runTest {
- repo.onCustomizationRequested(standardCustomizationRequestInfo)
+ repo.onCustomizationRequested(standardAddCustomShortcutRequestInfo)
val shortcutBeingCustomized = repo.getShortcutBeingCustomized()
- assertThat(shortcutBeingCustomized).isEqualTo(standardCustomizationRequestInfo)
+ assertThat(shortcutBeingCustomized).isEqualTo(standardAddCustomShortcutRequestInfo)
}
}
@@ -223,7 +211,7 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
fun buildInputGestureDataForShortcutBeingCustomized_noKeyCombinationSelected_returnsNull() {
testScope.runTest {
helper.toggle(deviceId = 123)
- repo.onCustomizationRequested(standardCustomizationRequestInfo)
+ repo.onCustomizationRequested(standardAddCustomShortcutRequestInfo)
val inputGestureData = repo.buildInputGestureDataForShortcutBeingCustomized()
@@ -235,46 +223,32 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
fun buildInputGestureDataForShortcutBeingCustomized_successfullyBuildInputGestureData() {
testScope.runTest {
helper.toggle(deviceId = 123)
- repo.onCustomizationRequested(standardCustomizationRequestInfo)
+ repo.onCustomizationRequested(standardAddCustomShortcutRequestInfo)
repo.updateUserKeyCombination(standardKeyCombination)
val inputGestureData = repo.buildInputGestureDataForShortcutBeingCustomized()
// using toString as we're testing for only structural equality not referential.
// inputGestureData is a java class and isEqual Tests for referential equality
// as well which would cause this assert to fail
- assertThat(inputGestureData.toString()).isEqualTo(standardInputGestureData.toString())
+ assertThat(inputGestureData.toString()).isEqualTo(allAppsInputGestureData.toString())
}
}
- private val standardCustomizationRequestInfo =
- ShortcutCustomizationRequestInfo.Add(
- label = "Open apps list",
- categoryType = ShortcutCategoryType.System,
- subCategoryLabel = "System controls",
- )
-
- private val standardKeyCombination =
- KeyCombination(
- modifiers = META_META_ON or META_SHIFT_ON or META_META_LEFT_ON or META_SHIFT_RIGHT_ON,
- keyCode = KEYCODE_A,
- )
-
- private val allSupportedModifiers =
- META_META_ON or
- META_CTRL_ON or
- META_FUNCTION_ON or
- META_SHIFT_ON or
- META_ALT_ON or
- META_SYM_ON
-
- private val standardInputGestureData =
- InputGestureData.Builder()
- .setKeyGestureType(KEY_GESTURE_TYPE_ALL_APPS)
- .setTrigger(
- createKeyTrigger(
- /* keycode = */ standardKeyCombination.keyCode!!,
- /* modifierState = */ standardKeyCombination.modifiers and allSupportedModifiers,
- )
- )
- .build()
+ @Test
+ @EnableFlags(FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES, FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
+ fun deleteShortcut_successfullyRetrievesGestureDataAndDeletesShortcut() {
+ testScope.runTest {
+ whenever(inputManager.getCustomInputGestures(anyOrNull()))
+ .thenReturn(listOf(allAppsInputGestureData, goHomeInputGestureData))
+ whenever(inputManager.removeCustomInputGesture(allAppsInputGestureData))
+ .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_SUCCESS)
+
+ helper.toggle(deviceId = 123)
+ repo.onCustomizationRequested(standardDeleteCustomShortcutRequestInfo)
+
+ val result = repo.deleteShortcutCurrentlyBeingCustomized()
+
+ assertThat(result).isEqualTo(ShortcutCustomizationRequestResult.SUCCESS)
+ }
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
index a1e7ef4ac5a3..8466eab2aca6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
@@ -19,9 +19,23 @@ package com.android.systemui.keyboard.shortcut.data.source
import android.hardware.input.InputGestureData
import android.hardware.input.InputGestureData.createKeyTrigger
import android.hardware.input.KeyGestureEvent
+import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
+import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_HOME
+import android.os.SystemClock
import android.view.KeyEvent
+import android.view.KeyEvent.ACTION_DOWN
+import android.view.KeyEvent.KEYCODE_A
+import android.view.KeyEvent.META_ALT_ON
+import android.view.KeyEvent.META_CTRL_ON
+import android.view.KeyEvent.META_FUNCTION_ON
+import android.view.KeyEvent.META_META_LEFT_ON
+import android.view.KeyEvent.META_META_ON
+import android.view.KeyEvent.META_SHIFT_ON
+import android.view.KeyEvent.META_SHIFT_RIGHT_ON
+import android.view.KeyEvent.META_SYM_ON
import android.view.KeyboardShortcutGroup
import android.view.KeyboardShortcutInfo
+import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
@@ -29,9 +43,11 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import com.android.systemui.keyboard.shortcut.shared.model.shortcut
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutCustomizationUiState
import com.android.systemui.res.R
object TestShortcuts {
@@ -525,4 +541,110 @@ object TestShortcuts {
keyGestureType = KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER
),
)
+
+ val standardAddCustomShortcutRequestInfo =
+ ShortcutCustomizationRequestInfo.Add(
+ label = "Open apps list",
+ categoryType = System,
+ subCategoryLabel = "System controls",
+ )
+
+ val standardDeleteCustomShortcutRequestInfo =
+ ShortcutCustomizationRequestInfo.Delete(
+ label = "Open apps list",
+ categoryType = System,
+ subCategoryLabel = "System controls",
+ )
+
+ val standardKeyCombination =
+ KeyCombination(
+ modifiers = META_META_ON or META_SHIFT_ON or META_META_LEFT_ON or META_SHIFT_RIGHT_ON,
+ keyCode = KEYCODE_A,
+ )
+
+ const val ALL_SUPPORTED_MODIFIERS =
+ META_META_ON or
+ META_CTRL_ON or
+ META_FUNCTION_ON or
+ META_SHIFT_ON or
+ META_ALT_ON or
+ META_SYM_ON
+
+ val allAppsInputGestureData: InputGestureData =
+ InputGestureData.Builder()
+ .setKeyGestureType(KEY_GESTURE_TYPE_ALL_APPS)
+ .setTrigger(
+ createKeyTrigger(
+ /* keycode = */ standardKeyCombination.keyCode!!,
+ /* modifierState = */ standardKeyCombination.modifiers and
+ ALL_SUPPORTED_MODIFIERS,
+ )
+ )
+ .build()
+
+ val goHomeInputGestureData: InputGestureData =
+ InputGestureData.Builder()
+ .setKeyGestureType(KEY_GESTURE_TYPE_HOME)
+ .setTrigger(
+ createKeyTrigger(
+ /* keycode = */ standardKeyCombination.keyCode!!,
+ /* modifierState = */ standardKeyCombination.modifiers and
+ ALL_SUPPORTED_MODIFIERS,
+ )
+ )
+ .build()
+
+ val expectedStandardDeleteShortcutUiState =
+ ShortcutCustomizationUiState.DeleteShortcutDialog(isDialogShowing = false)
+
+ val keyDownEventWithoutActionKeyPressed =
+ androidx.compose.ui.input.key.KeyEvent(
+ android.view.KeyEvent(
+ /* downTime = */ SystemClock.uptimeMillis(),
+ /* eventTime = */ SystemClock.uptimeMillis(),
+ /* action = */ ACTION_DOWN,
+ /* code = */ KEYCODE_A,
+ /* repeat = */ 0,
+ /* metaState = */ META_CTRL_ON,
+ )
+ )
+
+ val keyDownEventWithActionKeyPressed =
+ androidx.compose.ui.input.key.KeyEvent(
+ android.view.KeyEvent(
+ /* downTime = */ SystemClock.uptimeMillis(),
+ /* eventTime = */ SystemClock.uptimeMillis(),
+ /* action = */ ACTION_DOWN,
+ /* code = */ KEYCODE_A,
+ /* repeat = */ 0,
+ /* metaState = */ META_CTRL_ON or META_META_ON,
+ )
+ )
+
+ val keyUpEventWithActionKeyPressed =
+ androidx.compose.ui.input.key.KeyEvent(
+ android.view.KeyEvent(
+ /* downTime = */ SystemClock.uptimeMillis(),
+ /* eventTime = */ SystemClock.uptimeMillis(),
+ /* action = */ ACTION_DOWN,
+ /* code = */ KEYCODE_A,
+ /* repeat = */ 0,
+ /* metaState = */ 0,
+ )
+ )
+
+ val standardAddShortcutRequest =
+ ShortcutCustomizationRequestInfo.Add(
+ label = "Standard shortcut",
+ categoryType = ShortcutCategoryType.System,
+ subCategoryLabel = "Standard subcategory",
+ )
+
+ val expectedStandardAddShortcutUiState =
+ ShortcutCustomizationUiState.AddShortcutDialog(
+ shortcutLabel = "Standard shortcut",
+ defaultCustomShortcutModifierKey =
+ ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta),
+ isDialogShowing = false,
+ )
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
index 032979447861..0a4198a99bba 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest.kt
@@ -32,7 +32,8 @@ import java.util.Optional
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -125,14 +126,11 @@ class HomeControlsKeyguardQuickAffordanceConfigParameterizedStateTest : SysuiTes
)
underTest =
- HomeControlsKeyguardQuickAffordanceConfig(
- context = context,
- component = component,
- )
+ HomeControlsKeyguardQuickAffordanceConfig(context = context, component = component)
}
@Test
- fun state() = runBlockingTest {
+ fun state() = runTest(UnconfinedTestDispatcher()) {
whenever(component.isEnabled()).thenReturn(isFeatureEnabled)
whenever(controlsController.getFavorites())
.thenReturn(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
index 7d68cc0a3560..0003d07d1e2f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
@@ -19,19 +19,20 @@ package com.android.systemui.keyguard.data.quickaffordance
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable
import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
+import com.android.systemui.res.R
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import java.util.Optional
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -54,14 +55,11 @@ class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))
underTest =
- HomeControlsKeyguardQuickAffordanceConfig(
- context = context,
- component = component,
- )
+ HomeControlsKeyguardQuickAffordanceConfig(context = context, component = component)
}
@Test
- fun state_whenCannotShowWhileLocked_returnsHidden() = runBlockingTest {
+ fun state_whenCannotShowWhileLocked_returnsHidden() = runTest(UnconfinedTestDispatcher()) {
whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))
whenever(component.isEnabled()).thenReturn(true)
whenever(component.getTileImageId()).thenReturn(R.drawable.controls_icon)
@@ -81,7 +79,7 @@ class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
}
@Test
- fun state_whenListingControllerIsMissing_returnsHidden() = runBlockingTest {
+ fun state_whenListingControllerIsMissing_returnsHidden() = runTest(UnconfinedTestDispatcher()) {
whenever(component.isEnabled()).thenReturn(true)
whenever(component.getTileImageId()).thenReturn(R.drawable.controls_icon)
whenever(component.getTileTitleId()).thenReturn(R.string.quick_controls_title)
@@ -100,23 +98,26 @@ class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
}
@Test
- fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsTrue() = runBlockingTest {
- whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))
+ fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsTrue() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(true))
- val onClickedResult = underTest.onTriggered(expandable)
+ val onClickedResult = underTest.onTriggered(expandable)
- assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
- assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked).isTrue()
- }
+ assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
+ assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked)
+ .isTrue()
+ }
@Test
- fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsFalse() = runBlockingTest {
- whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))
+ fun onQuickAffordanceTriggered_canShowWhileLockedSettingIsFalse() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(component.canShowWhileLockedSetting).thenReturn(MutableStateFlow(false))
- val onClickedResult = underTest.onTriggered(expandable)
+ val onClickedResult = underTest.onTriggered(expandable)
- assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
- assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked)
- .isFalse()
- }
+ assertThat(onClickedResult).isInstanceOf(OnTriggeredResult.StartActivity::class.java)
+ assertThat((onClickedResult as OnTriggeredResult.StartActivity).canShowWhileLocked)
+ .isFalse()
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
index ca64cec98b2e..05a74c038cc1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
@@ -29,7 +29,7 @@ import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -56,60 +56,63 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
}
@Test
- fun affordance_setsUpRegistrationAndDeliversInitialModel() = runBlockingTest {
- whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
- var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
-
- val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+ fun affordance_setsUpRegistrationAndDeliversInitialModel() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
+ var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+
+ val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+
+ val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
+ verify(controller).addCallback(callbackCaptor.capture())
+ verify(controller)
+ .registerQRCodeScannerChangeObservers(
+ QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
+ QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE,
+ )
+ assertVisibleState(latest)
- val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
- verify(controller).addCallback(callbackCaptor.capture())
- verify(controller)
- .registerQRCodeScannerChangeObservers(
- QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
- QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE
- )
- assertVisibleState(latest)
-
- job.cancel()
- verify(controller).removeCallback(callbackCaptor.value)
- }
+ job.cancel()
+ verify(controller).removeCallback(callbackCaptor.value)
+ }
@Test
- fun affordance_scannerActivityChanged_deliversModelWithUpdatedIntent() = runBlockingTest {
- whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
- var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
- val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
- val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
- verify(controller).addCallback(callbackCaptor.capture())
+ fun affordance_scannerActivityChanged_deliversModelWithUpdatedIntent() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
+ var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+ val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+ val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
+ verify(controller).addCallback(callbackCaptor.capture())
- whenever(controller.intent).thenReturn(INTENT_2)
- callbackCaptor.value.onQRCodeScannerActivityChanged()
+ whenever(controller.intent).thenReturn(INTENT_2)
+ callbackCaptor.value.onQRCodeScannerActivityChanged()
- assertVisibleState(latest)
+ assertVisibleState(latest)
- job.cancel()
- verify(controller).removeCallback(callbackCaptor.value)
- }
+ job.cancel()
+ verify(controller).removeCallback(callbackCaptor.value)
+ }
@Test
- fun affordance_scannerPreferenceChanged_deliversVisibleModel() = runBlockingTest {
- var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
- val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
- val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
- verify(controller).addCallback(callbackCaptor.capture())
+ fun affordance_scannerPreferenceChanged_deliversVisibleModel() =
+ runTest(UnconfinedTestDispatcher()) {
+ var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
+ val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
+ val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
+ verify(controller).addCallback(callbackCaptor.capture())
- whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
- callbackCaptor.value.onQRCodeScannerPreferenceChanged()
+ whenever(controller.isEnabledForLockScreenButton).thenReturn(true)
+ callbackCaptor.value.onQRCodeScannerPreferenceChanged()
- assertVisibleState(latest)
+ assertVisibleState(latest)
- job.cancel()
- verify(controller).removeCallback(callbackCaptor.value)
- }
+ job.cancel()
+ verify(controller).removeCallback(callbackCaptor.value)
+ }
@Test
- fun affordance_scannerPreferenceChanged_deliversNone() = runBlockingTest {
+ fun affordance_scannerPreferenceChanged_deliversNone() = runTest(UnconfinedTestDispatcher()) {
var latest: KeyguardQuickAffordanceConfig.LockScreenState? = null
val job = underTest.lockScreenState.onEach { latest = it }.launchIn(this)
val callbackCaptor = argumentCaptor<QRCodeScannerController.Callback>()
@@ -128,30 +131,29 @@ class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
fun onQuickAffordanceTriggered() {
assertThat(underTest.onTriggered(mock()))
.isEqualTo(
- OnTriggeredResult.StartActivity(
- intent = INTENT_1,
- canShowWhileLocked = true,
- )
+ OnTriggeredResult.StartActivity(intent = INTENT_1, canShowWhileLocked = true)
)
}
@Test
- fun getPickerScreenState_enabledIfConfiguredOnDevice_isEnabledForPickerState() = runTest {
- whenever(controller.isAllowedOnLockScreen).thenReturn(true)
- whenever(controller.isAbleToLaunchScannerActivity).thenReturn(true)
+ fun getPickerScreenState_enabledIfConfiguredOnDevice_isEnabledForPickerState() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(controller.isAllowedOnLockScreen).thenReturn(true)
+ whenever(controller.isAbleToLaunchScannerActivity).thenReturn(true)
- assertThat(underTest.getPickerScreenState())
- .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
- }
+ assertThat(underTest.getPickerScreenState())
+ .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.Default())
+ }
@Test
- fun getPickerScreenState_disabledIfConfiguredOnDevice_isDisabledForPickerState() = runTest {
- whenever(controller.isAllowedOnLockScreen).thenReturn(true)
- whenever(controller.isAbleToLaunchScannerActivity).thenReturn(false)
-
- assertThat(underTest.getPickerScreenState())
- .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
- }
+ fun getPickerScreenState_disabledIfConfiguredOnDevice_isDisabledForPickerState() =
+ runTest(UnconfinedTestDispatcher()) {
+ whenever(controller.isAllowedOnLockScreen).thenReturn(true)
+ whenever(controller.isAbleToLaunchScannerActivity).thenReturn(false)
+
+ assertThat(underTest.getPickerScreenState())
+ .isEqualTo(KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice)
+ }
private fun assertVisibleState(latest: KeyguardQuickAffordanceConfig.LockScreenState?) {
assertThat(latest)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
index 2c12f8782ddc..e60a52c12c0b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
@@ -24,6 +24,7 @@ import com.android.systemui.authentication.data.repository.FakeAuthenticationRep
import com.android.systemui.authentication.domain.interactor.authenticationInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.flags.DisableSceneContainer
import com.android.systemui.flags.EnableSceneContainer
@@ -34,10 +35,12 @@ import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticati
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.model.asIterable
+import com.android.systemui.scene.data.model.sceneStackOf
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
-import com.android.systemui.scene.data.repository.sceneContainerRepository
import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.domain.interactor.sceneBackInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.testKosmos
@@ -85,7 +88,7 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
fun setUp() {
// lazy value needs to be called here otherwise flow collection misbehaves
underTest.value
- kosmos.sceneContainerRepository.setTransitionState(sceneTransitions)
+ kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Lockscreen))
}
@Test
@@ -967,15 +970,56 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
@Test
@EnableSceneContainer
+ fun lockscreenVisibilityWithScenes_staysTrue_despiteEnteringIndirectly() =
+ testScope.runTest {
+ val isDeviceUnlocked by
+ collectLastValue(
+ kosmos.deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked }
+ )
+ assertThat(isDeviceUnlocked).isFalse()
+
+ val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+ assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+
+ val lockscreenVisibility by collectLastValue(underTest.value.lockscreenVisibility)
+ assertThat(lockscreenVisibility).isTrue()
+
+ kosmos.setSceneTransition(Idle(Scenes.Shade))
+ kosmos.sceneInteractor.changeScene(Scenes.Shade, "")
+ kosmos.sceneBackInteractor.onSceneChange(from = Scenes.Lockscreen, to = Scenes.Shade)
+ assertThat(currentScene).isEqualTo(Scenes.Shade)
+ assertThat(lockscreenVisibility).isTrue()
+ val sceneBackStack by collectLastValue(kosmos.sceneBackInteractor.backStack)
+ assertThat(sceneBackStack?.asIterable()?.toList()).isEqualTo(listOf(Scenes.Lockscreen))
+
+ val isDeviceEntered by collectLastValue(kosmos.deviceEntryInteractor.isDeviceEntered)
+ val isDeviceEnteredDirectly by
+ collectLastValue(kosmos.deviceEntryInteractor.isDeviceEnteredDirectly)
+ runCurrent()
+ assertThat(isDeviceEntered).isFalse()
+ assertThat(isDeviceEnteredDirectly).isFalse()
+
+ kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
+ kosmos.sceneBackInteractor.updateBackStack { sceneStackOf(Scenes.Gone) }
+ assertThat(sceneBackStack?.asIterable()?.toList()).isEqualTo(listOf(Scenes.Gone))
+
+ assertThat(isDeviceEntered).isTrue()
+ assertThat(isDeviceEnteredDirectly).isFalse()
+ assertThat(isDeviceUnlocked).isTrue()
+ assertThat(lockscreenVisibility).isTrue()
+ }
+
+ @Test
+ @EnableSceneContainer
fun sceneContainer_usingGoingAwayAnimation_duringTransitionToGone() =
testScope.runTest {
val usingKeyguardGoingAwayAnimation by
collectLastValue(underTest.value.usingKeyguardGoingAwayAnimation)
- sceneTransitions.value = lsToGone
+ kosmos.setSceneTransition(lsToGone)
assertThat(usingKeyguardGoingAwayAnimation).isTrue()
- sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone)
+ kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone))
assertThat(usingKeyguardGoingAwayAnimation).isFalse()
}
@@ -986,14 +1030,14 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
val usingKeyguardGoingAwayAnimation by
collectLastValue(underTest.value.usingKeyguardGoingAwayAnimation)
- sceneTransitions.value = lsToGone
+ kosmos.setSceneTransition(lsToGone)
surfaceBehindIsAnimatingFlow.emit(true)
assertThat(usingKeyguardGoingAwayAnimation).isTrue()
- sceneTransitions.value = ObservableTransitionState.Idle(Scenes.Gone)
+ kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone))
assertThat(usingKeyguardGoingAwayAnimation).isTrue()
- sceneTransitions.value = goneToLs
+ kosmos.setSceneTransition(goneToLs)
assertThat(usingKeyguardGoingAwayAnimation).isTrue()
surfaceBehindIsAnimatingFlow.emit(false)
@@ -1003,11 +1047,6 @@ class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
companion object {
private val progress = MutableStateFlow(0f)
- private val sceneTransitions =
- MutableStateFlow<ObservableTransitionState>(
- ObservableTransitionState.Idle(Scenes.Lockscreen)
- )
-
private val lsToGone =
ObservableTransitionState.Transition(
Scenes.Lockscreen,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
index 5c4b7432e18d..62cc76345c87 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelTest.kt
@@ -32,12 +32,11 @@ import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
-import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
-import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
import com.android.systemui.kosmos.testScope
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.power.data.repository.fakePowerRepository
@@ -48,7 +47,6 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.TransitionKeys
import com.android.systemui.scene.ui.viewmodel.SceneContainerEdge
import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.math.pow
@@ -69,12 +67,13 @@ import platform.test.runner.parameterized.Parameters
class LockscreenUserActionsViewModelTest : SysuiTestCase() {
companion object {
- private const val parameterCount = 6
+ private const val parameterCount = 7
@Parameters(
name =
"canSwipeToEnter={0}, downWithTwoPointers={1}, downFromEdge={2}," +
- " isSingleShade={3}, isCommunalAvailable={4}, isShadeTouchable={5}"
+ " isSingleShade={3}, isCommunalAvailable={4}, isShadeTouchable={5}," +
+ " isOccluded={6}"
)
@JvmStatic
fun combinations() = buildList {
@@ -87,6 +86,7 @@ class LockscreenUserActionsViewModelTest : SysuiTestCase() {
/* isSingleShade= */ combination and 8 != 0,
/* isCommunalAvailable= */ combination and 16 != 0,
/* isShadeTouchable= */ combination and 32 != 0,
+ /* isOccluded= */ combination and 64 != 0,
)
.also { check(it.size == parameterCount) }
)
@@ -116,10 +116,12 @@ class LockscreenUserActionsViewModelTest : SysuiTestCase() {
downFromEdge: Boolean,
isNarrowScreen: Boolean,
isShadeTouchable: Boolean,
+ isOccluded: Boolean,
): SceneKey? {
return when {
!isShadeTouchable -> null
- downFromEdge && isNarrowScreen -> Scenes.QuickSettings
+ downFromEdge && isNarrowScreen && !isOccluded -> Scenes.QuickSettings
+ downFromEdge && isNarrowScreen && isOccluded -> null
else -> Scenes.Shade
}
}
@@ -168,8 +170,9 @@ class LockscreenUserActionsViewModelTest : SysuiTestCase() {
@JvmField @Parameter(3) var isNarrowScreen: Boolean = true
@JvmField @Parameter(4) var isCommunalAvailable: Boolean = false
@JvmField @Parameter(5) var isShadeTouchable: Boolean = false
+ @JvmField @Parameter(6) var isOccluded: Boolean = false
- private val underTest by lazy { createLockscreenSceneViewModel() }
+ private val underTest by lazy { kosmos.lockscreenUserActionsViewModel }
@Test
@EnableFlags(Flags.FLAG_COMMUNAL_HUB)
@@ -196,6 +199,7 @@ class LockscreenUserActionsViewModelTest : SysuiTestCase() {
WakefulnessState.ASLEEP
}
)
+ kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = isOccluded)
val userActions by collectLastValue(underTest.actions)
val downDestination =
@@ -217,6 +221,7 @@ class LockscreenUserActionsViewModelTest : SysuiTestCase() {
downFromEdge = downFromEdge,
isNarrowScreen = isNarrowScreen,
isShadeTouchable = isShadeTouchable,
+ isOccluded = isOccluded,
)
)
@@ -285,6 +290,7 @@ class LockscreenUserActionsViewModelTest : SysuiTestCase() {
WakefulnessState.ASLEEP
}
)
+ kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = isOccluded)
val userActions by collectLastValue(underTest.actions)
@@ -354,12 +360,4 @@ class LockscreenUserActionsViewModelTest : SysuiTestCase() {
)
)
}
-
- private fun createLockscreenSceneViewModel(): LockscreenUserActionsViewModel {
- return LockscreenUserActionsViewModel(
- deviceEntryInteractor = kosmos.deviceEntryInteractor,
- communalInteractor = kosmos.communalInteractor,
- shadeInteractor = kosmos.shadeInteractor,
- )
- }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
index 02825a55923f..ff00bfb540c6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepositoryTest.kt
@@ -18,6 +18,7 @@ package com.android.systemui.mediaprojection.data.repository
import android.hardware.display.displayManager
import android.media.projection.MediaProjectionInfo
+import android.media.projection.StopReason
import android.os.Binder
import android.os.Handler
import android.os.UserHandle
@@ -339,8 +340,9 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
@Test
fun stopProjecting_invokesManager() =
testScope.runTest {
- repo.stopProjecting()
+ repo.stopProjecting(StopReason.STOP_QS_TILE)
- verify(fakeMediaProjectionManager.mediaProjectionManager).stopActiveProjection()
+ verify(fakeMediaProjectionManager.mediaProjectionManager)
+ .stopActiveProjection(StopReason.STOP_QS_TILE)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt
index 4acf3ee7878b..645efae16b8b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionStateTest.kt
@@ -27,7 +27,7 @@ import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
class MutableSelectionStateTest : SysuiTestCase() {
- private val underTest = MutableSelectionState({}, {})
+ private val underTest = MutableSelectionState()
@Test
fun selectTile_isCorrectlySelected() {
@@ -48,120 +48,6 @@ class MutableSelectionStateTest : SysuiTestCase() {
assertThat(underTest.selection?.manual).isFalse()
}
- @Test
- fun startResize_createsResizingState() {
- assertThat(underTest.resizingState).isNull()
-
- // Resizing starts but no tile is selected
- underTest.onResizingDragStart(TileWidths(0, 0, 1))
- assertThat(underTest.resizingState).isNull()
-
- // Resizing starts with a selected tile
- underTest.select(TEST_SPEC, manual = true)
- underTest.onResizingDragStart(TileWidths(0, 0, 1))
-
- assertThat(underTest.resizingState).isNotNull()
- }
-
- @Test
- fun endResize_clearsResizingState() {
- val spec = TileSpec.create("testSpec")
-
- // Resizing starts with a selected tile
- underTest.select(spec, manual = true)
- underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
- assertThat(underTest.resizingState).isNotNull()
-
- underTest.onResizingDragEnd()
- assertThat(underTest.resizingState).isNull()
- }
-
- @Test
- fun unselect_clearsResizingState() {
- // Resizing starts with a selected tile
- underTest.select(TEST_SPEC, manual = true)
- underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
- assertThat(underTest.resizingState).isNotNull()
-
- underTest.unSelect()
- assertThat(underTest.resizingState).isNull()
- }
-
- @Test
- fun onResizingDrag_updatesResizingState() {
- // Resizing starts with a selected tile
- underTest.select(TEST_SPEC, manual = true)
- underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
- assertThat(underTest.resizingState).isNotNull()
-
- underTest.onResizingDrag(5f)
- assertThat(underTest.resizingState?.width).isEqualTo(5)
-
- underTest.onResizingDrag(2f)
- assertThat(underTest.resizingState?.width).isEqualTo(7)
-
- underTest.onResizingDrag(-6f)
- assertThat(underTest.resizingState?.width).isEqualTo(1)
- }
-
- @Test
- fun onResizingDrag_receivesResizeCallback() {
- var resized = false
- val onResize: (TileSpec) -> Unit = {
- assertThat(it).isEqualTo(TEST_SPEC)
- resized = !resized
- }
- val underTest = MutableSelectionState(onResize = onResize, {})
-
- // Resizing starts with a selected tile
- underTest.select(TEST_SPEC, true)
- underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
- assertThat(underTest.resizingState).isNotNull()
-
- // Drag under the threshold
- underTest.onResizingDrag(1f)
- assertThat(resized).isFalse()
-
- // Drag over the threshold
- underTest.onResizingDrag(5f)
- assertThat(resized).isTrue()
-
- // Drag back under the threshold
- underTest.onResizingDrag(-5f)
- assertThat(resized).isFalse()
- }
-
- @Test
- fun onResizingEnded_receivesResizeEndCallback() {
- var resizeEnded = false
- val onResizeEnd: (TileSpec) -> Unit = { resizeEnded = true }
- val underTest = MutableSelectionState({}, onResizeEnd = onResizeEnd)
-
- // Resizing starts with a selected tile
- underTest.select(TEST_SPEC, true)
- underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
-
- underTest.onResizingDragEnd()
- assertThat(resizeEnded).isTrue()
- }
-
- @Test
- fun onResizingEnded_setsSelectionAutomatically() {
- val underTest = MutableSelectionState({}, {})
-
- // Resizing starts with a selected tile
- underTest.select(TEST_SPEC, manual = true)
- underTest.onResizingDragStart(TileWidths(base = 0, min = 0, max = 10))
-
- // Assert the selection was manual
- assertThat(underTest.selection?.manual).isTrue()
-
- underTest.onResizingDragEnd()
-
- // Assert the selection is no longer manual due to the resizing
- assertThat(underTest.selection?.manual).isFalse()
- }
-
companion object {
private val TEST_SPEC = TileSpec.create("testSpec")
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingStateTest.kt
index 6e66783da44e..2206f4dcf5a8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingStateTest.kt
@@ -19,7 +19,9 @@ package com.android.systemui.qs.panels.ui.compose.selection
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.pipeline.shared.TileSpec
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
@@ -27,36 +29,32 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ResizingStateTest : SysuiTestCase() {
- @Test
- fun drag_updatesStateCorrectly() {
- var resized = false
- val underTest =
- ResizingState(TileWidths(base = 0, min = 0, max = 10)) { resized = !resized }
-
- assertThat(underTest.width).isEqualTo(0)
+ private val underTest =
+ ResizingState(TileSpec.create("a"), startsAsIcon = true).apply { updateAnchors(10f, 20f) }
- underTest.onDrag(2f)
- assertThat(underTest.width).isEqualTo(2)
-
- underTest.onDrag(1f)
- assertThat(underTest.width).isEqualTo(3)
- assertThat(resized).isTrue()
+ @Test
+ fun newResizingState_setInitialValueCorrectly() {
+ assertThat(underTest.anchoredDraggableState.currentValue).isEqualTo(QSDragAnchor.Icon)
+ }
- underTest.onDrag(-1f)
- assertThat(underTest.width).isEqualTo(2)
- assertThat(resized).isFalse()
+ @Test
+ fun updateAnchors_setBoundsCorrectly() {
+ assertThat(underTest.bounds).isEqualTo(10f to 20f)
}
@Test
- fun dragOutOfBounds_isClampedCorrectly() {
- val underTest = ResizingState(TileWidths(base = 0, min = 0, max = 10)) {}
+ fun dragOverThreshold_resizesToLarge() = runTest {
+ underTest.anchoredDraggableState.anchoredDrag { dragTo(16f) }
- assertThat(underTest.width).isEqualTo(0)
+ assertThat(underTest.temporaryResizeOperation.spec).isEqualTo(TileSpec.create("a"))
+ assertThat(underTest.temporaryResizeOperation.toIcon).isFalse()
+ }
- underTest.onDrag(100f)
- assertThat(underTest.width).isEqualTo(10)
+ @Test
+ fun dragUnderThreshold_staysIcon() = runTest {
+ underTest.anchoredDraggableState.anchoredDrag { dragTo(12f) }
- underTest.onDrag(-200f)
- assertThat(underTest.width).isEqualTo(0)
+ assertThat(underTest.temporaryResizeOperation.spec).isEqualTo(TileSpec.create("a"))
+ assertThat(underTest.temporaryResizeOperation.toIcon).isTrue()
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelTest.kt
new file mode 100644
index 000000000000..f2bfd729f74a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelTest.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.qs.panels.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.fakeFalsingManager
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class EditModeButtonViewModelTest : SysuiTestCase() {
+ val kosmos = testKosmos()
+
+ val underTest = kosmos.editModeButtonViewModelFactory.create()
+
+ @Test
+ fun falsingFalseTap_editModeDoesntStart() =
+ kosmos.runTest {
+ val isEditing by collectLastValue(editModeViewModel.isEditing)
+
+ fakeFalsingManager.setFalseTap(true)
+
+ underTest.onButtonClick()
+ runCurrent()
+
+ assertThat(isEditing).isFalse()
+ }
+
+ @Test
+ fun falsingNotFalseTap_editModeStarted() =
+ kosmos.runTest {
+ val isEditing by collectLastValue(editModeViewModel.isEditing)
+
+ fakeFalsingManager.setFalseTap(false)
+
+ underTest.onButtonClick()
+ runCurrent()
+
+ assertThat(isEditing).isTrue()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorTest.kt
new file mode 100644
index 000000000000..08225a7770d2
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorTest.kt
@@ -0,0 +1,145 @@
+/*
+ * 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.scene.domain.interactor
+
+import android.app.StatusBarManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.Swipe
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.scene.shared.model.Overlays
+import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
+import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.launch
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DisabledContentInteractorTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+
+ private val underTest = kosmos.disabledContentInteractor
+
+ @Test
+ fun isDisabled_notificationsShade() =
+ kosmos.runTest {
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NONE)
+ assertThat(underTest.isDisabled(Overlays.NotificationsShade)).isFalse()
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NOTIFICATION_SHADE)
+ assertThat(underTest.isDisabled(Overlays.NotificationsShade)).isTrue()
+ }
+
+ @Test
+ fun isDisabled_qsShade() =
+ kosmos.runTest {
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NONE)
+ assertThat(underTest.isDisabled(Overlays.QuickSettingsShade)).isFalse()
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+ assertThat(underTest.isDisabled(Overlays.QuickSettingsShade)).isTrue()
+ }
+
+ @Test
+ fun repeatWhenDisabled() =
+ kosmos.runTest {
+ var notificationDisabledCount = 0
+ applicationCoroutineScope.launch {
+ underTest.repeatWhenDisabled(Overlays.NotificationsShade) {
+ notificationDisabledCount++
+ }
+ }
+ var qsDisabledCount = 0
+ applicationCoroutineScope.launch {
+ underTest.repeatWhenDisabled(Overlays.QuickSettingsShade) { qsDisabledCount++ }
+ }
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+ assertThat(notificationDisabledCount).isEqualTo(0)
+ assertThat(qsDisabledCount).isEqualTo(1)
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 =
+ StatusBarManager.DISABLE2_NOTIFICATION_SHADE or
+ StatusBarManager.DISABLE2_QUICK_SETTINGS
+ )
+ assertThat(notificationDisabledCount).isEqualTo(1)
+ assertThat(qsDisabledCount).isEqualTo(1)
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NOTIFICATION_SHADE)
+ assertThat(notificationDisabledCount).isEqualTo(1)
+ assertThat(qsDisabledCount).isEqualTo(1)
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+ assertThat(notificationDisabledCount).isEqualTo(1)
+ assertThat(qsDisabledCount).isEqualTo(2)
+ }
+
+ @Test
+ fun filteredUserActions() =
+ kosmos.runTest {
+ val map =
+ mapOf<UserAction, UserActionResult>(
+ Swipe.Up to UserActionResult.ShowOverlay(Overlays.NotificationsShade),
+ Swipe.Down to UserActionResult.ShowOverlay(Overlays.QuickSettingsShade),
+ )
+ val unfiltered = MutableStateFlow(map)
+ val filtered by collectLastValue(underTest.filteredUserActions(unfiltered))
+ assertThat(filtered).isEqualTo(map)
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NOTIFICATION_SHADE)
+ assertThat(filtered)
+ .isEqualTo(
+ mapOf(Swipe.Down to UserActionResult.ShowOverlay(Overlays.QuickSettingsShade))
+ )
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+ assertThat(filtered)
+ .isEqualTo(
+ mapOf(Swipe.Up to UserActionResult.ShowOverlay(Overlays.NotificationsShade))
+ )
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(
+ disable2 =
+ StatusBarManager.DISABLE2_NOTIFICATION_SHADE or
+ StatusBarManager.DISABLE2_QUICK_SETTINGS
+ )
+ assertThat(filtered).isEqualTo(emptyMap<UserAction, UserActionResult>())
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index 7fe3d8d08afa..48edded5df18 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -18,6 +18,7 @@
package com.android.systemui.scene.domain.interactor
+import android.app.StatusBarManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
@@ -30,6 +31,8 @@ import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.repository.Idle
import com.android.systemui.scene.data.repository.Transition
@@ -43,6 +46,8 @@ import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.SceneFamilies
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.shared.model.fakeSceneDataSource
+import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
+import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -523,4 +528,51 @@ class SceneInteractorTest : SysuiTestCase() {
assertThat(currentScene).isEqualTo(Scenes.Gone)
}
+
+ @Test
+ fun showOverlay_overlayDisabled_doesNothing() =
+ kosmos.runTest {
+ val currentOverlays by collectLastValue(underTest.currentOverlays)
+ val disabledOverlay = Overlays.QuickSettingsShade
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+ assertThat(disabledContentInteractor.isDisabled(disabledOverlay)).isTrue()
+ assertThat(currentOverlays).doesNotContain(disabledOverlay)
+
+ underTest.showOverlay(disabledOverlay, "reason")
+
+ assertThat(currentOverlays).doesNotContain(disabledOverlay)
+ }
+
+ @Test
+ fun replaceOverlay_withDisabledOverlay_doesNothing() =
+ kosmos.runTest {
+ val currentOverlays by collectLastValue(underTest.currentOverlays)
+ val showingOverlay = Overlays.NotificationsShade
+ underTest.showOverlay(showingOverlay, "reason")
+ assertThat(currentOverlays).isEqualTo(setOf(showingOverlay))
+ val disabledOverlay = Overlays.QuickSettingsShade
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_QUICK_SETTINGS)
+ assertThat(disabledContentInteractor.isDisabled(disabledOverlay)).isTrue()
+
+ underTest.replaceOverlay(showingOverlay, disabledOverlay, "reason")
+
+ assertThat(currentOverlays).isEqualTo(setOf(showingOverlay))
+ }
+
+ @Test
+ fun changeScene_toDisabledScene_doesNothing() =
+ kosmos.runTest {
+ val currentScene by collectLastValue(underTest.currentScene)
+ val disabledScene = Scenes.Shade
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NOTIFICATION_SHADE)
+ assertThat(disabledContentInteractor.isDisabled(disabledScene)).isTrue()
+ assertThat(currentScene).isNotEqualTo(disabledScene)
+
+ underTest.changeScene(disabledScene, "reason")
+
+ assertThat(currentScene).isNotEqualTo(disabledScene)
+ }
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index cca847effe94..5d49c113a539 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -81,6 +81,9 @@ import com.android.systemui.keyguard.domain.interactor.scenetransition.lockscree
import com.android.systemui.keyguard.shared.model.FailFingerprintAuthenticationStatus
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
+import com.android.systemui.kosmos.collectLastValue
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.model.sysUiState
import com.android.systemui.power.data.repository.fakePowerRepository
@@ -101,6 +104,8 @@ import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.shade.shared.flag.DualShade
import com.android.systemui.shared.system.QuickStepContract
import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
+import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
import com.android.systemui.statusbar.notification.data.repository.HeadsUpRowRepository
@@ -2673,6 +2678,25 @@ class SceneContainerStartableTest : SysuiTestCase() {
assertThat(isAlternateBouncerVisible).isFalse()
}
+ @Test
+ fun handleDisableFlags() =
+ kosmos.runTest {
+ underTest.start()
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
+ sceneInteractor.changeScene(Scenes.Shade, "reason")
+ sceneInteractor.showOverlay(Overlays.NotificationsShade, "reason")
+ assertThat(currentScene).isEqualTo(Scenes.Shade)
+ assertThat(currentOverlays).contains(Overlays.NotificationsShade)
+
+ fakeDisableFlagsRepository.disableFlags.value =
+ DisableFlagsModel(disable2 = StatusBarManager.DISABLE2_NOTIFICATION_SHADE)
+ runCurrent()
+
+ assertThat(currentScene).isNotEqualTo(Scenes.Shade)
+ assertThat(currentOverlays).isEmpty()
+ }
+
private fun TestScope.emulateSceneTransition(
transitionStateFlow: MutableStateFlow<ObservableTransitionState>,
toScene: SceneKey,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
index 8ef1e568cd58..016a24acd461 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractorTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.shade.domain.interactor
import android.content.Context
+import android.content.MutableContextWrapper
import android.content.res.Configuration
import android.content.res.Resources
import android.view.Display
@@ -30,6 +31,7 @@ import com.android.systemui.display.shared.model.DisplayWindowProperties
import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.shade.data.repository.FakeShadeDisplayRepository
import com.android.systemui.statusbar.phone.ConfigurationForwarder
+import java.util.Optional
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -64,13 +66,14 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
private val interactor =
ShadeDisplaysInteractor(
- shadeRootview,
+ Optional.of(shadeRootview),
positionRepository,
- defaultContext,
+ MutableContextWrapper(defaultContext),
+ resources,
contextStore,
- testScope,
+ testScope.backgroundScope,
configurationForwarder,
- testScope.coroutineContext,
+ testScope.backgroundScope.coroutineContext,
)
@Before
@@ -79,7 +82,6 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
whenever(display.displayId).thenReturn(0)
whenever(resources.configuration).thenReturn(configuration)
- whenever(resources.configuration).thenReturn(configuration)
whenever(defaultContext.displayId).thenReturn(0)
whenever(defaultContext.getSystemService(any())).thenReturn(defaultWm)
@@ -124,7 +126,6 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
whenever(display.displayId).thenReturn(0)
positionRepository.setDisplayId(1)
interactor.start()
- testScope.advanceUntilIdle()
verify(defaultWm).removeView(eq(shadeRootview))
verify(secondaryWm).addView(eq(shadeRootview), any())
@@ -135,10 +136,8 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
whenever(display.displayId).thenReturn(0)
positionRepository.setDisplayId(0)
interactor.start()
- testScope.advanceUntilIdle()
positionRepository.setDisplayId(1)
- testScope.advanceUntilIdle()
verify(defaultWm).removeView(eq(shadeRootview))
verify(secondaryWm).addView(eq(shadeRootview), any())
@@ -149,10 +148,8 @@ class ShadeDisplaysInteractorTest : SysuiTestCase() {
whenever(display.displayId).thenReturn(0)
positionRepository.setDisplayId(0)
interactor.start()
- testScope.advanceUntilIdle()
positionRepository.setDisplayId(1)
- testScope.advanceUntilIdle()
verify(configurationForwarder).onConfigurationChanged(eq(configuration))
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
index 1f2925528077..544d20145db3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.collection.coordinator;
import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.Notification.FLAG_PROMOTED_ONGOING;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_MIN;
@@ -24,12 +25,18 @@ import static android.app.NotificationManager.IMPORTANCE_MIN;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Person;
import android.content.Intent;
import android.graphics.Color;
import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -38,11 +45,14 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -136,6 +146,60 @@ public class ColorizedFgsCoordinatorTest extends SysuiTestCase {
assertFalse(mFgsSection.isInSection(mEntryBuilder.build()));
}
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+ public void testIncludePromotedOngoingInSection_flagEnabled() {
+ // GIVEN the notification has FLAG_PROMOTED_ONGOING
+ mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
+
+ // THEN the entry is in the fgs section
+ assertTrue(mFgsSection.isInSection(mEntryBuilder.build()));
+ }
+
+ @Test
+ @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+ public void testDiscludePromotedOngoingInSection_flagDisabled() {
+ // GIVEN the notification has FLAG_PROMOTED_ONGOING
+ mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
+
+ // THEN the entry is NOT in the fgs section
+ assertFalse(mFgsSection.isInSection(mEntryBuilder.build()));
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+ public void promoterSelectsPromotedOngoing_flagEnabled() {
+ ArgumentCaptor<NotifPromoter> captor = ArgumentCaptor.forClass(NotifPromoter.class);
+ verify(mNotifPipeline).addPromoter(captor.capture());
+ NotifPromoter promoter = captor.getValue();
+
+ // GIVEN the notification has FLAG_PROMOTED_ONGOING
+ mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, true);
+
+ // THEN the entry is promoted to top level
+ assertTrue(promoter.shouldPromoteToTopLevel(mEntryBuilder.build()));
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+ public void promoterIgnoresNonPromotedOngoing_flagEnabled() {
+ ArgumentCaptor<NotifPromoter> captor = ArgumentCaptor.forClass(NotifPromoter.class);
+ verify(mNotifPipeline).addPromoter(captor.capture());
+ NotifPromoter promoter = captor.getValue();
+
+ // GIVEN the notification does not have FLAG_PROMOTED_ONGOING
+ mEntryBuilder.setFlag(mContext, FLAG_PROMOTED_ONGOING, false);
+
+ // THEN the entry is NOT promoted to top level
+ assertFalse(promoter.shouldPromoteToTopLevel(mEntryBuilder.build()));
+ }
+
+ @Test
+ @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+ public void noPromoterAdded_flagDisabled() {
+ verify(mNotifPipeline, never()).addPromoter(any());
+ }
+
private Notification.CallStyle makeCallStyle() {
final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0,
new Intent("action"), PendingIntent.FLAG_IMMUTABLE);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index a940ed4d70f9..f48fd3c998b1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -838,27 +838,26 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
testScope.runTest {
var notificationCount = 10
val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> notificationCount }
- val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
+ val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
advanceTimeBy(50L)
showLockscreen()
shadeTestUtil.setSplitShade(false)
configurationRepository.onAnyConfigurationChange()
- assertThat(maxNotifications).isEqualTo(10)
+ assertThat(config?.maxNotifications).isEqualTo(10)
// Also updates when directly requested (as it would from NotificationStackScrollLayout)
notificationCount = 25
sharedNotificationContainerInteractor.notificationStackChanged()
advanceTimeBy(50L)
- assertThat(maxNotifications).isEqualTo(25)
+ assertThat(config?.maxNotifications).isEqualTo(25)
// Also ensure another collection starts with the same value. As an example, folding
// then unfolding will restart the coroutine and it must get the last value immediately.
- val newMaxNotifications by
- collectLastValue(underTest.getMaxNotifications(calculateSpace))
+ val newConfig by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
advanceTimeBy(50L)
- assertThat(newMaxNotifications).isEqualTo(25)
+ assertThat(newConfig?.maxNotifications).isEqualTo(25)
}
@Test
@@ -866,18 +865,18 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
testScope.runTest {
var notificationCount = 10
val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> notificationCount }
- val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
+ val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
advanceTimeBy(50L)
showLockscreen()
shadeTestUtil.setSplitShade(false)
configurationRepository.onAnyConfigurationChange()
- assertThat(maxNotifications).isEqualTo(10)
+ assertThat(config?.maxNotifications).isEqualTo(10)
// Shade expanding... still 10
shadeTestUtil.setLockscreenShadeExpansion(0.5f)
- assertThat(maxNotifications).isEqualTo(10)
+ assertThat(config?.maxNotifications).isEqualTo(10)
notificationCount = 25
@@ -885,20 +884,20 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
shadeTestUtil.setLockscreenShadeTracking(true)
// Should still be 10, since the user is interacting
- assertThat(maxNotifications).isEqualTo(10)
+ assertThat(config?.maxNotifications).isEqualTo(10)
shadeTestUtil.setLockscreenShadeTracking(false)
shadeTestUtil.setLockscreenShadeExpansion(0f)
// Stopped tracking, show 25
- assertThat(maxNotifications).isEqualTo(25)
+ assertThat(config?.maxNotifications).isEqualTo(25)
}
@Test
fun maxNotificationsOnShade() =
testScope.runTest {
val calculateSpace = { space: Float, useExtraShelfSpace: Boolean -> 10 }
- val maxNotifications by collectLastValue(underTest.getMaxNotifications(calculateSpace))
+ val config by collectLastValue(underTest.getLockscreenDisplayConfig(calculateSpace))
advanceTimeBy(50L)
// Show lockscreen with shade expanded
@@ -908,7 +907,7 @@ class SharedNotificationContainerViewModelTest(flags: FlagsParameterization) : S
configurationRepository.onAnyConfigurationChange()
// -1 means No Limit
- assertThat(maxNotifications).isEqualTo(-1)
+ assertThat(config?.maxNotifications).isEqualTo(-1)
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
new file mode 100644
index 000000000000..0b0b1e45d604
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/MultiDisplayAutoHideControllerStoreTest.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import android.platform.test.annotations.EnableFlags
+import android.view.Display.DEFAULT_DISPLAY
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
+class MultiDisplayAutoHideControllerStoreTest : SysuiTestCase() {
+
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+ private val testScope = kosmos.testScope
+ private val fakeDisplayRepository = kosmos.displayRepository
+
+ // Lazy so that @EnableFlags has time to run before underTest is instantiated.
+ private val underTest by lazy { kosmos.multiDisplayAutoHideControllerStore }
+
+ @Before fun addDisplays() = runBlocking { fakeDisplayRepository.addDisplay(DEFAULT_DISPLAY) }
+
+ @Test
+ fun beforeDisplayRemoved_doesNotStopInstances() =
+ testScope.runTest {
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+
+ verify(instance, never()).stop()
+ }
+
+ @Test
+ fun displayRemoved_stopsInstance() =
+ testScope.runTest {
+ val instance = underTest.forDisplay(DEFAULT_DISPLAY)
+
+ fakeDisplayRepository.removeDisplay(DEFAULT_DISPLAY)
+
+ verify(instance).stop()
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
index 20b273ae7f4e..d5651ec8ce6c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
@@ -22,21 +22,25 @@ import android.content.Context
import android.content.pm.UserInfo
import android.os.UserHandle
import android.os.UserManager
+import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.GuestResetOrExitSessionReceiver
import com.android.systemui.GuestResumeSessionReceiver
import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.statusbar.policy.DeviceProvisionedController
+import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.user.domain.model.ShowDialogRequestModel
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.kotlinArgumentCaptor
import com.android.systemui.util.mockito.whenever
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.TestCoroutineScope
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -48,6 +52,7 @@ import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper
class GuestUserInteractorTest : SysuiTestCase() {
@Mock private lateinit var manager: UserManager
@@ -64,16 +69,15 @@ class GuestUserInteractorTest : SysuiTestCase() {
private lateinit var underTest: GuestUserInteractor
- private lateinit var scope: TestCoroutineScope
- private lateinit var repository: FakeUserRepository
+ private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+ private val scope = kosmos.testScope
+ private val repository = FakeUserRepository()
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
whenever(manager.createGuest(any())).thenReturn(GUEST_USER_INFO)
- scope = TestCoroutineScope()
- repository = FakeUserRepository()
repository.setUserInfos(ALL_USERS)
underTest = initGuestUserInteractor(context)
@@ -83,8 +87,8 @@ class GuestUserInteractorTest : SysuiTestCase() {
GuestUserInteractor(
applicationContext = context,
applicationScope = scope,
- mainDispatcher = IMMEDIATE,
- backgroundDispatcher = IMMEDIATE,
+ mainDispatcher = kosmos.testDispatcher,
+ backgroundDispatcher = kosmos.testDispatcher,
manager = manager,
repository = repository,
deviceProvisionedController = deviceProvisionedController,
@@ -92,7 +96,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
refreshUsersScheduler =
RefreshUsersScheduler(
applicationScope = scope,
- mainDispatcher = IMMEDIATE,
+ mainDispatcher = kosmos.testDispatcher,
repository = repository,
),
uiEventLogger = uiEventLogger,
@@ -118,7 +122,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun onDeviceBootCompleted_allowedToAdd_createGuest() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
setAllowedToAdd()
underTest.onDeviceBootCompleted()
@@ -129,7 +133,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun onDeviceBootCompleted_awaitProvisioning_andCreateGuest() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
setAllowedToAdd(isAllowed = false)
underTest.onDeviceBootCompleted()
val captor =
@@ -145,7 +149,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun createAndSwitchTo() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
underTest.createAndSwitchTo(
showDialog = showDialog,
dismissDialog = dismissDialog,
@@ -160,7 +164,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun createAndSwitchTo_failsToCreate_doesNotSwitchTo() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
whenever(manager.createGuest(any())).thenReturn(null)
underTest.createAndSwitchTo(
@@ -177,7 +181,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_returnsToTargetUser() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
repository.setSelectedUserInfo(GUEST_USER_INFO)
val targetUserId = NON_GUEST_USER_INFO.id
@@ -197,7 +201,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_returnsToLastNonGuest() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
val expectedUserId = NON_GUEST_USER_INFO.id
whenever(manager.getUserInfo(expectedUserId)).thenReturn(NON_GUEST_USER_INFO)
repository.lastSelectedNonGuestUserId = expectedUserId
@@ -219,7 +223,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_lastNonGuestWasRemoved_returnsToMainUser() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
val removedUserId = 310
val mainUserId = 10
repository.lastSelectedNonGuestUserId = removedUserId
@@ -242,7 +246,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_guestWasEphemeral_itIsRemoved() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
repository.setUserInfos(listOf(NON_GUEST_USER_INFO, EPHEMERAL_GUEST_USER_INFO))
repository.setSelectedUserInfo(EPHEMERAL_GUEST_USER_INFO)
@@ -265,7 +269,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_forceRemoveGuest_itIsRemoved() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
repository.setSelectedUserInfo(GUEST_USER_INFO)
val targetUserId = NON_GUEST_USER_INFO.id
@@ -287,7 +291,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_selectedDifferentFromGuestUser_doNothing() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
underTest.exit(
@@ -304,7 +308,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun exit_selectedIsActuallyNotAguestUser_doNothing() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
underTest.exit(
@@ -321,7 +325,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun remove_returnsToTargetUser() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
repository.setSelectedUserInfo(GUEST_USER_INFO)
@@ -342,7 +346,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun remove_selectedDifferentFromGuestUser_doNothing() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
@@ -359,7 +363,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
@Test
fun remove_selectedIsActuallyNotAguestUser_doNothing() =
- runBlocking(IMMEDIATE) {
+ kosmos.runTest {
whenever(manager.markGuestForDeletion(anyInt())).thenReturn(true)
repository.setSelectedUserInfo(NON_GUEST_USER_INFO)
@@ -395,11 +399,7 @@ class GuestUserInteractorTest : SysuiTestCase() {
companion object {
private val IMMEDIATE = Dispatchers.Main.immediate
private val NON_GUEST_USER_INFO =
- UserInfo(
- /* id= */ 818,
- /* name= */ "non_guest",
- /* flags= */ UserInfo.FLAG_FULL,
- )
+ UserInfo(/* id= */ 818, /* name= */ "non_guest", /* flags= */ UserInfo.FLAG_FULL)
private val GUEST_USER_INFO =
UserInfo(
/* id= */ 669,
@@ -416,10 +416,6 @@ class GuestUserInteractorTest : SysuiTestCase() {
/* flags= */ UserInfo.FLAG_EPHEMERAL or UserInfo.FLAG_FULL,
UserManager.USER_TYPE_FULL_GUEST,
)
- private val ALL_USERS =
- listOf(
- NON_GUEST_USER_INFO,
- GUEST_USER_INFO,
- )
+ private val ALL_USERS = listOf(NON_GUEST_USER_INFO, GUEST_USER_INFO)
}
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockAnimations.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockAnimations.kt
new file mode 100644
index 000000000000..2df14a86e77c
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockAnimations.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.plugins.clocks
+
+import android.view.View
+import com.android.systemui.plugins.annotations.ProtectedInterface
+
+/** Methods which trigger various clock animations */
+@ProtectedInterface
+interface ClockAnimations {
+ /** Runs an enter animation (if any) */
+ fun enter()
+
+ /** Sets how far into AOD the device currently is. */
+ fun doze(fraction: Float)
+
+ /** Sets how far into the folding animation the device is. */
+ fun fold(fraction: Float)
+
+ /** Runs the battery animation (if any). */
+ fun charge()
+
+ /**
+ * Runs when the clock's position changed during the move animation.
+ *
+ * @param fromLeft the [View.getLeft] position of the clock, before it started moving.
+ * @param direction the direction in which it is moving. A positive number means right, and
+ * negative means left.
+ * @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
+ * it finished moving.
+ * @deprecated use {@link #onPositionUpdated(float, float)} instead.
+ */
+ fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float)
+
+ /**
+ * Runs when the clock's position changed during the move animation.
+ *
+ * @param distance is the total distance in pixels to offset the glyphs when animation
+ * completes. Negative distance means we are animating the position towards the center.
+ * @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
+ * it finished moving.
+ */
+ fun onPositionUpdated(distance: Float, fraction: Float)
+
+ /**
+ * Runs when swiping clock picker, swipingFraction: 1.0 -> clock is scaled up in the preview,
+ * 0.0 -> clock is scaled down in the shade; previewRatio is previewSize / screenSize
+ */
+ fun onPickerCarouselSwiping(swipingFraction: Float)
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockConfig.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockConfig.kt
new file mode 100644
index 000000000000..d84d89087349
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockConfig.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.plugins.clocks
+
+/**
+ * Exposes the rendering capabilities of this clock to SystemUI so that it can be hosted and render
+ * correctly in SystemUI's process. Ideally all clocks could be rendered identically, but in
+ * practice we different clocks require different behavior from SystemUI.
+ */
+data class ClockConfig(
+ val id: ClockId,
+
+ /** Localized name of the clock */
+ val name: String,
+
+ /** Localized accessibility description for the clock */
+ val description: String,
+
+ /** Transition to AOD should move smartspace like large clock instead of small clock */
+ val useAlternateSmartspaceAODTransition: Boolean = false,
+
+ /** Deprecated version of isReactiveToTone; moved to ClockPickerConfig */
+ @Deprecated("TODO(b/352049256): Remove in favor of ClockPickerConfig.isReactiveToTone")
+ val isReactiveToTone: Boolean = true,
+
+ /** True if the clock is large frame clock, which will use weather in compose. */
+ val useCustomClockScene: Boolean = false,
+)
+
+/** Render configuration options for a specific clock face. */
+data class ClockFaceConfig(
+ /** Expected interval between calls to onTimeTick. Can always reduce to PER_MINUTE in AOD. */
+ val tickRate: ClockTickRate = ClockTickRate.PER_MINUTE,
+
+ /** Call to check whether the clock consumes weather data */
+ val hasCustomWeatherDataDisplay: Boolean = false,
+
+ /**
+ * Whether this clock has a custom position update animation. If true, the keyguard will call
+ * `onPositionUpdated` to notify the clock of a position update animation. If false, a default
+ * animation will be used (e.g. a simple translation).
+ */
+ val hasCustomPositionUpdatedAnimation: Boolean = false,
+
+ /** True if the clock is large frame clock, which will use weatherBlueprint in compose. */
+ val useCustomClockScene: Boolean = false,
+)
+
+/** Tick rates for clocks */
+enum class ClockTickRate(val value: Int) {
+ PER_MINUTE(2), // Update the clock once per minute.
+ PER_SECOND(1), // Update the clock once per second.
+ PER_FRAME(0), // Update the clock every second.
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt
new file mode 100644
index 000000000000..32fec3277f18
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockController.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.plugins.clocks
+
+import com.android.systemui.plugins.annotations.ProtectedInterface
+import com.android.systemui.plugins.annotations.SimpleProperty
+import java.io.PrintWriter
+
+/** Interface for controlling an active clock */
+@ProtectedInterface
+interface ClockController {
+ @get:SimpleProperty
+ /** A small version of the clock, appropriate for smaller viewports */
+ val smallClock: ClockFaceController
+
+ @get:SimpleProperty
+ /** A large version of the clock, appropriate when a bigger viewport is available */
+ val largeClock: ClockFaceController
+
+ @get:SimpleProperty
+ /** Determines the way the hosting app should behave when rendering either clock face */
+ val config: ClockConfig
+
+ @get:SimpleProperty
+ /** Events that clocks may need to respond to */
+ val events: ClockEvents
+
+ /** Initializes various rendering parameters. If never called, provides reasonable defaults. */
+ fun initialize(isDarkTheme: Boolean, dozeFraction: Float, foldFraction: Float)
+
+ /** Optional method for dumping debug information */
+ fun dump(pw: PrintWriter)
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt
new file mode 100644
index 000000000000..235475f6b202
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.plugins.clocks
+
+import com.android.systemui.plugins.annotations.ProtectedInterface
+import com.android.systemui.plugins.annotations.ProtectedReturn
+import java.util.Locale
+import java.util.TimeZone
+
+/** Events that should call when various rendering parameters change */
+@ProtectedInterface
+interface ClockEvents {
+ @get:ProtectedReturn("return false;")
+ /** Set to enable or disable swipe interaction */
+ var isReactiveTouchInteractionEnabled: Boolean // TODO(b/364664388): Remove/Rename
+
+ /** Call whenever timezone changes */
+ fun onTimeZoneChanged(timeZone: TimeZone)
+
+ /** Call whenever the text time format changes (12hr vs 24hr) */
+ fun onTimeFormatChanged(is24Hr: Boolean)
+
+ /** Call whenever the locale changes */
+ fun onLocaleChanged(locale: Locale)
+
+ /** Call whenever the weather data should update */
+ fun onWeatherDataChanged(data: WeatherData)
+
+ /** Call with alarm information */
+ fun onAlarmDataChanged(data: AlarmData)
+
+ /** Call with zen/dnd information */
+ fun onZenDataChanged(data: ZenData)
+
+ /** Update reactive axes for this clock */
+ fun onFontAxesChanged(axes: List<ClockFontAxisSetting>)
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceController.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceController.kt
new file mode 100644
index 000000000000..8a023f1c2388
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceController.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.plugins.clocks
+
+import android.view.View
+import com.android.systemui.plugins.annotations.ProtectedInterface
+import com.android.systemui.plugins.annotations.SimpleProperty
+
+/** Interface for a specific clock face version rendered by the clock */
+@ProtectedInterface
+interface ClockFaceController {
+ @get:SimpleProperty
+ @Deprecated("Prefer use of layout")
+ /** View that renders the clock face */
+ val view: View
+
+ @get:SimpleProperty
+ /** Layout specification for this clock */
+ val layout: ClockFaceLayout
+
+ @get:SimpleProperty
+ /** Determines the way the hosting app should behave when rendering this clock face */
+ val config: ClockFaceConfig
+
+ @get:SimpleProperty
+ /** Current theme information the clock is using */
+ val theme: ThemeConfig
+
+ @get:SimpleProperty
+ /** Events specific to this clock face */
+ val events: ClockFaceEvents
+
+ @get:SimpleProperty
+ /** Triggers for various animations */
+ val animations: ClockAnimations
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt
new file mode 100644
index 000000000000..029e54658f60
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceEvents.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.plugins.clocks
+
+import android.graphics.Rect
+import com.android.systemui.plugins.annotations.ProtectedInterface
+
+/** Events that have specific data about the related face */
+@ProtectedInterface
+interface ClockFaceEvents {
+ /** Call every tick to update the rendered time */
+ fun onTimeTick()
+
+ /**
+ * Call whenever the theme or seedColor is updated
+ *
+ * Theme can be specific to the clock face.
+ * - isDarkTheme -> clock should be light
+ * - !isDarkTheme -> clock should be dark
+ */
+ fun onThemeChanged(theme: ThemeConfig)
+
+ /**
+ * Call whenever font settings change. Pass in a target font size in pixels. The specific clock
+ * design is allowed to ignore this target size on a case-by-case basis.
+ */
+ fun onFontSettingChanged(fontSizePx: Float)
+
+ /**
+ * Target region information for the clock face. For small clock, this will match the bounds of
+ * the parent view mostly, but have a target height based on the height of the default clock.
+ * For large clocks, the parent view is the entire device size, but most clocks will want to
+ * render within the centered targetRect to avoid obstructing other elements. The specified
+ * targetRegion is relative to the parent view.
+ */
+ fun onTargetRegionChanged(targetRegion: Rect?)
+
+ /** Called to notify the clock about its display. */
+ fun onSecondaryDisplayChanged(onSecondaryDisplay: Boolean)
+}
+
+/** Contains Theming information for the clock face */
+data class ThemeConfig(
+ /** True if the clock should use dark theme (light text on dark background) */
+ val isDarkTheme: Boolean,
+
+ /**
+ * A clock specific seed color to use when theming, if any was specified by the user. A null
+ * value denotes that we should use the seed color for the current system theme.
+ */
+ val seedColor: Int?,
+)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt
new file mode 100644
index 000000000000..fb5ef02aa06a
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockFaceLayout.kt
@@ -0,0 +1,174 @@
+/*
+ * 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.plugins.clocks
+
+import android.content.Context
+import android.util.DisplayMetrics
+import android.view.View
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
+import androidx.constraintlayout.widget.ConstraintSet.END
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.constraintlayout.widget.ConstraintSet.TOP
+import androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT
+import com.android.internal.policy.SystemBarUtils
+import com.android.systemui.plugins.annotations.GeneratedImport
+import com.android.systemui.plugins.annotations.ProtectedInterface
+import com.android.systemui.plugins.annotations.ProtectedReturn
+
+/** Specifies layout information for the clock face */
+@ProtectedInterface
+@GeneratedImport("java.util.ArrayList")
+@GeneratedImport("android.view.View")
+interface ClockFaceLayout {
+ @get:ProtectedReturn("return new ArrayList<View>();")
+ /** All clock views to add to the root constraint layout before applying constraints. */
+ val views: List<View>
+
+ @ProtectedReturn("return constraints;")
+ /** Custom constraints to apply to Lockscreen ConstraintLayout. */
+ fun applyConstraints(constraints: ConstraintSet): ConstraintSet
+
+ @ProtectedReturn("return constraints;")
+ /** Custom constraints to apply to preview ConstraintLayout. */
+ fun applyPreviewConstraints(
+ clockPreviewConfig: ClockPreviewConfig,
+ constraints: ConstraintSet,
+ ): ConstraintSet
+
+ /** Apply specified AOD BurnIn parameters to this layout */
+ fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel)
+}
+
+/** Data class to contain AOD BurnIn information for correct aod rendering */
+data class AodClockBurnInModel(
+ /** Scale that the clock should render at to mitigate burnin */
+ val scale: Float,
+
+ /** X-Translation for the clock to mitigate burnin */
+ val translationX: Float,
+
+ /** Y-Translation for the clock to mitigate burnin */
+ val translationY: Float,
+)
+
+/** A ClockFaceLayout that applies the default lockscreen layout to a single view */
+class DefaultClockFaceLayout(val view: View) : ClockFaceLayout {
+ override val views = listOf(view)
+
+ override fun applyConstraints(constraints: ConstraintSet): ConstraintSet {
+ if (views.size != 1) {
+ throw IllegalArgumentException(
+ "Should have only one container view when using DefaultClockFaceLayout"
+ )
+ }
+ return constraints
+ }
+
+ override fun applyPreviewConstraints(
+ clockPreviewConfig: ClockPreviewConfig,
+ constraints: ConstraintSet,
+ ): ConstraintSet {
+ return applyDefaultPreviewConstraints(clockPreviewConfig, constraints)
+ }
+
+ override fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel) {
+ // Default clock doesn't need detailed control of view
+ }
+
+ companion object {
+ fun applyDefaultPreviewConstraints(
+ clockPreviewConfig: ClockPreviewConfig,
+ constraints: ConstraintSet,
+ ): ConstraintSet {
+ constraints.apply {
+ val context = clockPreviewConfig.previewContext
+ val lockscreenClockViewLargeId = getId(context, "lockscreen_clock_view_large")
+ constrainWidth(lockscreenClockViewLargeId, WRAP_CONTENT)
+ constrainHeight(lockscreenClockViewLargeId, WRAP_CONTENT)
+ constrainMaxHeight(lockscreenClockViewLargeId, 0)
+
+ val largeClockTopMargin =
+ SystemBarUtils.getStatusBarHeight(context) +
+ getDimen(context, "small_clock_padding_top") +
+ getDimen(context, "keyguard_smartspace_top_offset") +
+ getDimen(context, "date_weather_view_height") +
+ getDimen(context, "enhanced_smartspace_height")
+ connect(lockscreenClockViewLargeId, TOP, PARENT_ID, TOP, largeClockTopMargin)
+ connect(lockscreenClockViewLargeId, START, PARENT_ID, START)
+ connect(lockscreenClockViewLargeId, END, PARENT_ID, END)
+
+ // In preview, we'll show UDFPS icon for UDFPS devices
+ // and nothing for non-UDFPS devices,
+ // and we're not planning to add this vide in clockHostView
+ // so we only need position of device entry icon to constrain clock
+ // Copied calculation codes from applyConstraints in DefaultDeviceEntrySection
+ val bottomPaddingPx = getDimen(context, "lock_icon_margin_bottom")
+ val defaultDensity =
+ DisplayMetrics.DENSITY_DEVICE_STABLE.toFloat() /
+ DisplayMetrics.DENSITY_DEFAULT.toFloat()
+ val lockIconRadiusPx = (defaultDensity * 36).toInt()
+ val clockBottomMargin = bottomPaddingPx + 2 * lockIconRadiusPx
+
+ connect(lockscreenClockViewLargeId, BOTTOM, PARENT_ID, BOTTOM, clockBottomMargin)
+ val smallClockViewId = getId(context, "lockscreen_clock_view")
+ constrainWidth(smallClockViewId, WRAP_CONTENT)
+ constrainHeight(smallClockViewId, getDimen(context, "small_clock_height"))
+ connect(
+ smallClockViewId,
+ START,
+ PARENT_ID,
+ START,
+ getDimen(context, "clock_padding_start") +
+ getDimen(context, "status_view_margin_horizontal"),
+ )
+ val smallClockTopMargin =
+ getSmallClockTopPadding(
+ clockPreviewConfig = clockPreviewConfig,
+ SystemBarUtils.getStatusBarHeight(context),
+ )
+ connect(smallClockViewId, TOP, PARENT_ID, TOP, smallClockTopMargin)
+ }
+ return constraints
+ }
+
+ fun getId(context: Context, name: String): Int {
+ val packageName = context.packageName
+ val res = context.packageManager.getResourcesForApplication(packageName)
+ val id = res.getIdentifier(name, "id", packageName)
+ return id
+ }
+
+ fun getDimen(context: Context, name: String): Int {
+ val packageName = context.packageName
+ val res = context.resources
+ val id = res.getIdentifier(name, "dimen", packageName)
+ return if (id == 0) 0 else res.getDimensionPixelSize(id)
+ }
+
+ fun getSmallClockTopPadding(
+ clockPreviewConfig: ClockPreviewConfig,
+ statusBarHeight: Int,
+ ): Int {
+ return if (clockPreviewConfig.isShadeLayoutWide) {
+ getDimen(clockPreviewConfig.previewContext, "keyguard_split_shade_top_margin") -
+ if (clockPreviewConfig.isSceneContainerFlagEnabled) statusBarHeight else 0
+ } else {
+ getDimen(clockPreviewConfig.previewContext, "keyguard_clock_top_margin") +
+ if (!clockPreviewConfig.isSceneContainerFlagEnabled) statusBarHeight else 0
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockMessageBuffers.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockMessageBuffers.kt
new file mode 100644
index 000000000000..bec589ae139e
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockMessageBuffers.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.systemui.plugins.clocks
+
+import com.android.systemui.log.core.MessageBuffer
+
+/** MessageBuffers for clocks that want to log information to SystemUI dumps */
+data class ClockMessageBuffers(
+ /** Message buffer for general infrastructure */
+ val infraMessageBuffer: MessageBuffer,
+
+ /** Message buffer for small clock rendering */
+ val smallClockMessageBuffer: MessageBuffer,
+
+ /** Message buffer for large clock rendering */
+ val largeClockMessageBuffer: MessageBuffer,
+) {
+ constructor(buffer: MessageBuffer) : this(buffer, buffer, buffer) {}
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt
new file mode 100644
index 000000000000..1bc9367ce3c5
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.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.systemui.plugins.clocks
+
+import android.graphics.drawable.Drawable
+
+data class ClockPickerConfig
+@JvmOverloads
+constructor(
+ val id: String,
+
+ /** Localized name of the clock */
+ val name: String,
+
+ /** Localized accessibility description for the clock */
+ val description: String,
+
+ /* Static & lightweight thumbnail version of the clock */
+ val thumbnail: Drawable,
+
+ /** True if the clock will react to tone changes in the seed color */
+ val isReactiveToTone: Boolean = true,
+
+ /** Font axes that can be modified on this clock */
+ val axes: List<ClockFontAxis> = listOf(),
+)
+
+/** Represents an Axis that can be modified */
+data class ClockFontAxis(
+ /** Axis key, not user renderable */
+ val key: String,
+
+ /** Intended mode of user interaction */
+ val type: AxisType,
+
+ /** Maximum value the axis supports */
+ val maxValue: Float,
+
+ /** Minimum value the axis supports */
+ val minValue: Float,
+
+ /** Current value the axis is set to */
+ val currentValue: Float,
+
+ /** User-renderable name of the axis */
+ val name: String,
+
+ /** Description of the axis */
+ val description: String,
+) {
+ fun toSetting() = ClockFontAxisSetting(key, currentValue)
+
+ companion object {
+ fun merge(
+ fontAxes: List<ClockFontAxis>,
+ axisSettings: List<ClockFontAxisSetting>,
+ ): List<ClockFontAxis> {
+ val result = mutableListOf<ClockFontAxis>()
+ for (axis in fontAxes) {
+ val setting = axisSettings.firstOrNull { axis.key == it.key }
+ val output = setting?.let { axis.copy(currentValue = it.value) } ?: axis
+ result.add(output)
+ }
+ return result
+ }
+ }
+}
+
+/** Axis user interaction modes */
+enum class AxisType {
+ /** Continuous range between minValue & maxValue. */
+ Float,
+
+ /** Only minValue & maxValue are valid. No intermediate values between them are allowed. */
+ Boolean,
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt
new file mode 100644
index 000000000000..544b705c55c5
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPreviewConfig.kt
@@ -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.
+ */
+
+package com.android.systemui.plugins.clocks
+
+import android.content.Context
+
+data class ClockPreviewConfig(
+ val previewContext: Context,
+ val isShadeLayoutWide: Boolean,
+ val isSceneContainerFlagEnabled: Boolean = false,
+)
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
index fb9e96c820cf..7426f061b84c 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockProviderPlugin.kt
@@ -13,35 +13,11 @@
*/
package com.android.systemui.plugins.clocks
-import android.content.Context
-import android.graphics.Rect
-import android.graphics.drawable.Drawable
-import android.util.DisplayMetrics
-import android.view.View
-import androidx.constraintlayout.widget.ConstraintSet
-import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
-import androidx.constraintlayout.widget.ConstraintSet.END
-import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
-import androidx.constraintlayout.widget.ConstraintSet.START
-import androidx.constraintlayout.widget.ConstraintSet.TOP
-import androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT
-import com.android.internal.annotations.Keep
-import com.android.internal.policy.SystemBarUtils
-import com.android.systemui.log.core.MessageBuffer
import com.android.systemui.plugins.Plugin
import com.android.systemui.plugins.annotations.GeneratedImport
import com.android.systemui.plugins.annotations.ProtectedInterface
import com.android.systemui.plugins.annotations.ProtectedReturn
import com.android.systemui.plugins.annotations.ProvidesInterface
-import com.android.systemui.plugins.annotations.SimpleProperty
-import java.io.PrintWriter
-import java.util.Locale
-import java.util.TimeZone
-import org.json.JSONArray
-import org.json.JSONObject
-
-/** Identifies a clock design */
-typealias ClockId = String
/** A Plugin which exposes the ClockProvider interface */
@ProtectedInterface
@@ -74,509 +50,8 @@ interface ClockProvider {
fun getClockPickerConfig(settings: ClockSettings): ClockPickerConfig
}
-/** Interface for controlling an active clock */
-@ProtectedInterface
-interface ClockController {
- @get:SimpleProperty
- /** A small version of the clock, appropriate for smaller viewports */
- val smallClock: ClockFaceController
-
- @get:SimpleProperty
- /** A large version of the clock, appropriate when a bigger viewport is available */
- val largeClock: ClockFaceController
-
- @get:SimpleProperty
- /** Determines the way the hosting app should behave when rendering either clock face */
- val config: ClockConfig
-
- @get:SimpleProperty
- /** Events that clocks may need to respond to */
- val events: ClockEvents
-
- /** Initializes various rendering parameters. If never called, provides reasonable defaults. */
- fun initialize(isDarkTheme: Boolean, dozeFraction: Float, foldFraction: Float)
-
- /** Optional method for dumping debug information */
- fun dump(pw: PrintWriter)
-}
-
-/** Interface for a specific clock face version rendered by the clock */
-@ProtectedInterface
-interface ClockFaceController {
- @get:SimpleProperty
- @Deprecated("Prefer use of layout")
- /** View that renders the clock face */
- val view: View
-
- @get:SimpleProperty
- /** Layout specification for this clock */
- val layout: ClockFaceLayout
-
- @get:SimpleProperty
- /** Determines the way the hosting app should behave when rendering this clock face */
- val config: ClockFaceConfig
-
- @get:SimpleProperty
- /** Current theme information the clock is using */
- val theme: ThemeConfig
-
- @get:SimpleProperty
- /** Events specific to this clock face */
- val events: ClockFaceEvents
-
- @get:SimpleProperty
- /** Triggers for various animations */
- val animations: ClockAnimations
-}
-
-/** For clocks that want to report debug information */
-data class ClockMessageBuffers(
- /** Message buffer for general infra */
- val infraMessageBuffer: MessageBuffer,
-
- /** Message buffer for small clock renering */
- val smallClockMessageBuffer: MessageBuffer,
-
- /** Message buffer for large clock rendering */
- val largeClockMessageBuffer: MessageBuffer,
-) {
- constructor(buffer: MessageBuffer) : this(buffer, buffer, buffer) {}
-}
-
-data class AodClockBurnInModel(val scale: Float, val translationX: Float, val translationY: Float)
-
-/** Specifies layout information for the clock face */
-@ProtectedInterface
-@GeneratedImport("java.util.ArrayList")
-@GeneratedImport("android.view.View")
-interface ClockFaceLayout {
- @get:ProtectedReturn("return new ArrayList<View>();")
- /** All clock views to add to the root constraint layout before applying constraints. */
- val views: List<View>
-
- @ProtectedReturn("return constraints;")
- /** Custom constraints to apply to Lockscreen ConstraintLayout. */
- fun applyConstraints(constraints: ConstraintSet): ConstraintSet
-
- @ProtectedReturn("return constraints;")
- /** Custom constraints to apply to preview ConstraintLayout. */
- fun applyPreviewConstraints(context: Context, constraints: ConstraintSet): ConstraintSet
-
- fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel)
-}
-
-/** A ClockFaceLayout that applies the default lockscreen layout to a single view */
-class DefaultClockFaceLayout(val view: View) : ClockFaceLayout {
- // both small and large clock should have a container (RelativeLayout in
- // SimpleClockFaceController)
- override val views = listOf(view)
-
- override fun applyConstraints(constraints: ConstraintSet): ConstraintSet {
- if (views.size != 1) {
- throw IllegalArgumentException(
- "Should have only one container view when using DefaultClockFaceLayout"
- )
- }
- return constraints
- }
-
- override fun applyPreviewConstraints(
- context: Context,
- constraints: ConstraintSet,
- ): ConstraintSet {
- return applyDefaultPreviewConstraints(context, constraints)
- }
-
- override fun applyAodBurnIn(aodBurnInModel: AodClockBurnInModel) {
- // Default clock doesn't need detailed control of view
- }
-
- companion object {
- fun applyDefaultPreviewConstraints(
- context: Context,
- constraints: ConstraintSet,
- ): ConstraintSet {
- constraints.apply {
- val lockscreenClockViewLargeId = getId(context, "lockscreen_clock_view_large")
- constrainWidth(lockscreenClockViewLargeId, WRAP_CONTENT)
- constrainHeight(lockscreenClockViewLargeId, WRAP_CONTENT)
- constrainMaxHeight(lockscreenClockViewLargeId, 0)
-
- val largeClockTopMargin =
- SystemBarUtils.getStatusBarHeight(context) +
- getDimen(context, "small_clock_padding_top") +
- getDimen(context, "keyguard_smartspace_top_offset") +
- getDimen(context, "date_weather_view_height") +
- getDimen(context, "enhanced_smartspace_height")
- connect(lockscreenClockViewLargeId, TOP, PARENT_ID, TOP, largeClockTopMargin)
- connect(lockscreenClockViewLargeId, START, PARENT_ID, START)
- connect(lockscreenClockViewLargeId, END, PARENT_ID, END)
-
- // In preview, we'll show UDFPS icon for UDFPS devices
- // and nothing for non-UDFPS devices,
- // and we're not planning to add this vide in clockHostView
- // so we only need position of device entry icon to constrain clock
- // Copied calculation codes from applyConstraints in DefaultDeviceEntrySection
- val bottomPaddingPx = getDimen(context, "lock_icon_margin_bottom")
- val defaultDensity =
- DisplayMetrics.DENSITY_DEVICE_STABLE.toFloat() /
- DisplayMetrics.DENSITY_DEFAULT.toFloat()
- val lockIconRadiusPx = (defaultDensity * 36).toInt()
- val clockBottomMargin = bottomPaddingPx + 2 * lockIconRadiusPx
-
- connect(lockscreenClockViewLargeId, BOTTOM, PARENT_ID, BOTTOM, clockBottomMargin)
- val smallClockViewId = getId(context, "lockscreen_clock_view")
- constrainWidth(smallClockViewId, WRAP_CONTENT)
- constrainHeight(smallClockViewId, getDimen(context, "small_clock_height"))
- connect(
- smallClockViewId,
- START,
- PARENT_ID,
- START,
- getDimen(context, "clock_padding_start") +
- getDimen(context, "status_view_margin_horizontal"),
- )
- val smallClockTopMargin =
- getDimen(context, "keyguard_clock_top_margin") +
- SystemBarUtils.getStatusBarHeight(context)
- connect(smallClockViewId, TOP, PARENT_ID, TOP, smallClockTopMargin)
- }
- return constraints
- }
-
- fun getId(context: Context, name: String): Int {
- val packageName = context.packageName
- val res = context.packageManager.getResourcesForApplication(packageName)
- val id = res.getIdentifier(name, "id", packageName)
- return id
- }
-
- fun getDimen(context: Context, name: String): Int {
- val packageName = context.packageName
- val res = context.packageManager.getResourcesForApplication(packageName)
- val id = res.getIdentifier(name, "dimen", packageName)
- return if (id == 0) 0 else res.getDimensionPixelSize(id)
- }
- }
-}
-
-/** Events that should call when various rendering parameters change */
-@ProtectedInterface
-interface ClockEvents {
- @get:ProtectedReturn("return false;")
- /** Set to enable or disable swipe interaction */
- var isReactiveTouchInteractionEnabled: Boolean // TODO(b/364664388): Remove/Rename
-
- /** Call whenever timezone changes */
- fun onTimeZoneChanged(timeZone: TimeZone)
-
- /** Call whenever the text time format changes (12hr vs 24hr) */
- fun onTimeFormatChanged(is24Hr: Boolean)
-
- /** Call whenever the locale changes */
- fun onLocaleChanged(locale: Locale)
-
- /** Call whenever the weather data should update */
- fun onWeatherDataChanged(data: WeatherData)
-
- /** Call with alarm information */
- fun onAlarmDataChanged(data: AlarmData)
-
- /** Call with zen/dnd information */
- fun onZenDataChanged(data: ZenData)
-
- /** Update reactive axes for this clock */
- fun onFontAxesChanged(axes: List<ClockFontAxisSetting>)
-}
-
-/** Axis setting value for a clock */
-data class ClockFontAxisSetting(
- /** Axis key; matches ClockFontAxis.key */
- val key: String,
-
- /** Value to set this axis to */
- val value: Float,
-) {
- companion object {
- private val KEY_AXIS_KEY = "key"
- private val KEY_AXIS_VALUE = "value"
-
- fun toJson(setting: ClockFontAxisSetting): JSONObject {
- return JSONObject().apply {
- put(KEY_AXIS_KEY, setting.key)
- put(KEY_AXIS_VALUE, setting.value)
- }
- }
-
- fun toJson(settings: List<ClockFontAxisSetting>): JSONArray {
- return JSONArray().apply {
- for (axis in settings) {
- put(toJson(axis))
- }
- }
- }
-
- fun fromJson(jsonObj: JSONObject): ClockFontAxisSetting {
- return ClockFontAxisSetting(
- key = jsonObj.getString(KEY_AXIS_KEY),
- value = jsonObj.getDouble(KEY_AXIS_VALUE).toFloat(),
- )
- }
-
- fun fromJson(jsonArray: JSONArray): List<ClockFontAxisSetting> {
- val result = mutableListOf<ClockFontAxisSetting>()
- for (i in 0..jsonArray.length() - 1) {
- val obj = jsonArray.getJSONObject(i)
- if (obj == null) continue
- result.add(fromJson(obj))
- }
- return result
- }
-
- fun toFVar(settings: List<ClockFontAxisSetting>): String {
- val sb = StringBuilder()
- for (axis in settings) {
- if (sb.length > 0) sb.append(", ")
- sb.append("'${axis.key}' ${axis.value.toInt()}")
- }
- return sb.toString()
- }
- }
-}
-
-/** Methods which trigger various clock animations */
-@ProtectedInterface
-interface ClockAnimations {
- /** Runs an enter animation (if any) */
- fun enter()
-
- /** Sets how far into AOD the device currently is. */
- fun doze(fraction: Float)
-
- /** Sets how far into the folding animation the device is. */
- fun fold(fraction: Float)
-
- /** Runs the battery animation (if any). */
- fun charge()
-
- /**
- * Runs when the clock's position changed during the move animation.
- *
- * @param fromLeft the [View.getLeft] position of the clock, before it started moving.
- * @param direction the direction in which it is moving. A positive number means right, and
- * negative means left.
- * @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
- * it finished moving.
- * @deprecated use {@link #onPositionUpdated(float, float)} instead.
- */
- fun onPositionUpdated(fromLeft: Int, direction: Int, fraction: Float)
-
- /**
- * Runs when the clock's position changed during the move animation.
- *
- * @param distance is the total distance in pixels to offset the glyphs when animation
- * completes. Negative distance means we are animating the position towards the center.
- * @param fraction fraction of the clock movement. 0 means it is at the beginning, and 1 means
- * it finished moving.
- */
- fun onPositionUpdated(distance: Float, fraction: Float)
-
- /**
- * Runs when swiping clock picker, swipingFraction: 1.0 -> clock is scaled up in the preview,
- * 0.0 -> clock is scaled down in the shade; previewRatio is previewSize / screenSize
- */
- fun onPickerCarouselSwiping(swipingFraction: Float)
-}
-
-/** Events that have specific data about the related face */
-@ProtectedInterface
-interface ClockFaceEvents {
- /** Call every time tick */
- fun onTimeTick()
-
- /**
- * Call whenever the theme or seedColor is updated
- *
- * Theme can be specific to the clock face.
- * - isDarkTheme -> clock should be light
- * - !isDarkTheme -> clock should be dark
- */
- fun onThemeChanged(theme: ThemeConfig)
-
- /**
- * Call whenever font settings change. Pass in a target font size in pixels. The specific clock
- * design is allowed to ignore this target size on a case-by-case basis.
- */
- fun onFontSettingChanged(fontSizePx: Float)
-
- /**
- * Target region information for the clock face. For small clock, this will match the bounds of
- * the parent view mostly, but have a target height based on the height of the default clock.
- * For large clocks, the parent view is the entire device size, but most clocks will want to
- * render within the centered targetRect to avoid obstructing other elements. The specified
- * targetRegion is relative to the parent view.
- */
- fun onTargetRegionChanged(targetRegion: Rect?)
-
- /** Called to notify the clock about its display. */
- fun onSecondaryDisplayChanged(onSecondaryDisplay: Boolean)
-}
-
-data class ThemeConfig(val isDarkTheme: Boolean, val seedColor: Int?)
-
-/** Tick rates for clocks */
-enum class ClockTickRate(val value: Int) {
- PER_MINUTE(2), // Update the clock once per minute.
- PER_SECOND(1), // Update the clock once per second.
- PER_FRAME(0), // Update the clock every second.
-}
+/** Identifies a clock design */
+typealias ClockId = String
/** Some data about a clock design */
data class ClockMetadata(val clockId: ClockId)
-
-data class ClockPickerConfig
-@JvmOverloads
-constructor(
- val id: String,
-
- /** Localized name of the clock */
- val name: String,
-
- /** Localized accessibility description for the clock */
- val description: String,
-
- /* Static & lightweight thumbnail version of the clock */
- val thumbnail: Drawable,
-
- /** True if the clock will react to tone changes in the seed color */
- val isReactiveToTone: Boolean = true,
-
- /** Font axes that can be modified on this clock */
- val axes: List<ClockFontAxis> = listOf(),
-)
-
-/** Represents an Axis that can be modified */
-data class ClockFontAxis(
- /** Axis key, not user renderable */
- val key: String,
-
- /** Intended mode of user interaction */
- val type: AxisType,
-
- /** Maximum value the axis supports */
- val maxValue: Float,
-
- /** Minimum value the axis supports */
- val minValue: Float,
-
- /** Current value the axis is set to */
- val currentValue: Float,
-
- /** User-renderable name of the axis */
- val name: String,
-
- /** Description of the axis */
- val description: String,
-) {
- fun toSetting() = ClockFontAxisSetting(key, currentValue)
-
- companion object {
- fun merge(
- fontAxes: List<ClockFontAxis>,
- axisSettings: List<ClockFontAxisSetting>,
- ): List<ClockFontAxis> {
- val result = mutableListOf<ClockFontAxis>()
- for (axis in fontAxes) {
- val setting = axisSettings.firstOrNull { axis.key == it.key }
- val output = setting?.let { axis.copy(currentValue = it.value) } ?: axis
- result.add(output)
- }
- return result
- }
- }
-}
-
-/** Axis user interaction modes */
-enum class AxisType {
- /** Continuous range between minValue & maxValue. */
- Float,
-
- /** Only minValue & maxValue are valid. No intermediate values between them are allowed. */
- Boolean,
-}
-
-/** Render configuration for the full clock. Modifies the way systemUI behaves with this clock. */
-data class ClockConfig(
- val id: String,
-
- /** Localized name of the clock */
- val name: String,
-
- /** Localized accessibility description for the clock */
- val description: String,
-
- /** Transition to AOD should move smartspace like large clock instead of small clock */
- val useAlternateSmartspaceAODTransition: Boolean = false,
-
- /** Deprecated version of isReactiveToTone; moved to ClockPickerConfig */
- @Deprecated("TODO(b/352049256): Remove in favor of ClockPickerConfig.isReactiveToTone")
- val isReactiveToTone: Boolean = true,
-
- /** True if the clock is large frame clock, which will use weather in compose. */
- val useCustomClockScene: Boolean = false,
-)
-
-/** Render configuration options for a clock face. Modifies the way SystemUI behaves. */
-data class ClockFaceConfig(
- /** Expected interval between calls to onTimeTick. Can always reduce to PER_MINUTE in AOD. */
- val tickRate: ClockTickRate = ClockTickRate.PER_MINUTE,
-
- /** Call to check whether the clock consumes weather data */
- val hasCustomWeatherDataDisplay: Boolean = false,
-
- /**
- * Whether this clock has a custom position update animation. If true, the keyguard will call
- * `onPositionUpdated` to notify the clock of a position update animation. If false, a default
- * animation will be used (e.g. a simple translation).
- */
- val hasCustomPositionUpdatedAnimation: Boolean = false,
-
- /** True if the clock is large frame clock, which will use weatherBlueprint in compose. */
- val useCustomClockScene: Boolean = false,
-)
-
-/** Structure for keeping clock-specific settings */
-@Keep
-data class ClockSettings(
- val clockId: ClockId? = null,
- val seedColor: Int? = null,
- val axes: List<ClockFontAxisSetting> = listOf(),
-) {
- // Exclude metadata from equality checks
- var metadata: JSONObject = JSONObject()
-
- companion object {
- private val KEY_CLOCK_ID = "clockId"
- private val KEY_SEED_COLOR = "seedColor"
- private val KEY_METADATA = "metadata"
- private val KEY_AXIS_LIST = "axes"
-
- fun toJson(setting: ClockSettings): JSONObject {
- return JSONObject().apply {
- put(KEY_CLOCK_ID, setting.clockId)
- put(KEY_SEED_COLOR, setting.seedColor)
- put(KEY_METADATA, setting.metadata)
- put(KEY_AXIS_LIST, ClockFontAxisSetting.toJson(setting.axes))
- }
- }
-
- fun fromJson(json: JSONObject): ClockSettings {
- val clockId = if (!json.isNull(KEY_CLOCK_ID)) json.getString(KEY_CLOCK_ID) else null
- val seedColor = if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null
- val axisList = json.optJSONArray(KEY_AXIS_LIST)?.let(ClockFontAxisSetting::fromJson)
- return ClockSettings(clockId, seedColor, axisList ?: listOf()).apply {
- metadata = json.optJSONObject(KEY_METADATA) ?: JSONObject()
- }
- }
- }
-}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt
new file mode 100644
index 000000000000..6128c00f3843
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt
@@ -0,0 +1,110 @@
+/*
+ * 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.plugins.clocks
+
+import com.android.internal.annotations.Keep
+import org.json.JSONArray
+import org.json.JSONObject
+
+@Keep
+/** Structure for keeping clock-specific settings */
+data class ClockSettings(
+ val clockId: ClockId? = null,
+ val seedColor: Int? = null,
+ val axes: List<ClockFontAxisSetting> = listOf(),
+) {
+ // Exclude metadata from equality checks
+ var metadata: JSONObject = JSONObject()
+
+ companion object {
+ private val KEY_CLOCK_ID = "clockId"
+ private val KEY_SEED_COLOR = "seedColor"
+ private val KEY_METADATA = "metadata"
+ private val KEY_AXIS_LIST = "axes"
+
+ fun toJson(setting: ClockSettings): JSONObject {
+ return JSONObject().apply {
+ put(KEY_CLOCK_ID, setting.clockId)
+ put(KEY_SEED_COLOR, setting.seedColor)
+ put(KEY_METADATA, setting.metadata)
+ put(KEY_AXIS_LIST, ClockFontAxisSetting.toJson(setting.axes))
+ }
+ }
+
+ fun fromJson(json: JSONObject): ClockSettings {
+ val clockId = if (!json.isNull(KEY_CLOCK_ID)) json.getString(KEY_CLOCK_ID) else null
+ val seedColor = if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null
+ val axisList = json.optJSONArray(KEY_AXIS_LIST)?.let(ClockFontAxisSetting::fromJson)
+ return ClockSettings(clockId, seedColor, axisList ?: listOf()).apply {
+ metadata = json.optJSONObject(KEY_METADATA) ?: JSONObject()
+ }
+ }
+ }
+}
+
+@Keep
+/** Axis setting value for a clock */
+data class ClockFontAxisSetting(
+ /** Axis key; matches ClockFontAxis.key */
+ val key: String,
+
+ /** Value to set this axis to */
+ val value: Float,
+) {
+ companion object {
+ private val KEY_AXIS_KEY = "key"
+ private val KEY_AXIS_VALUE = "value"
+
+ fun toJson(setting: ClockFontAxisSetting): JSONObject {
+ return JSONObject().apply {
+ put(KEY_AXIS_KEY, setting.key)
+ put(KEY_AXIS_VALUE, setting.value)
+ }
+ }
+
+ fun toJson(settings: List<ClockFontAxisSetting>): JSONArray {
+ return JSONArray().apply {
+ for (axis in settings) {
+ put(toJson(axis))
+ }
+ }
+ }
+
+ fun fromJson(jsonObj: JSONObject): ClockFontAxisSetting {
+ return ClockFontAxisSetting(
+ key = jsonObj.getString(KEY_AXIS_KEY),
+ value = jsonObj.getDouble(KEY_AXIS_VALUE).toFloat(),
+ )
+ }
+
+ fun fromJson(jsonArray: JSONArray): List<ClockFontAxisSetting> {
+ val result = mutableListOf<ClockFontAxisSetting>()
+ for (i in 0..jsonArray.length() - 1) {
+ val obj = jsonArray.getJSONObject(i)
+ if (obj == null) continue
+ result.add(fromJson(obj))
+ }
+ return result
+ }
+
+ fun toFVar(settings: List<ClockFontAxisSetting>): String {
+ val sb = StringBuilder()
+ for (axis in settings) {
+ if (sb.length > 0) sb.append(", ")
+ sb.append("'${axis.key}' ${axis.value.toInt()}")
+ }
+ return sb.toString()
+ }
+ }
+}
diff --git a/packages/SystemUI/res/drawable/volume_background_top_legacy.xml b/packages/SystemUI/res/drawable/volume_background_top_legacy.xml
index 3cd87fc32061..58ae150f2539 100644
--- a/packages/SystemUI/res/drawable/volume_background_top_legacy.xml
+++ b/packages/SystemUI/res/drawable/volume_background_top_legacy.xml
@@ -16,7 +16,7 @@
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item>
+ <item android:gravity="bottom|end">
<shape>
<size android:width="@dimen/volume_dialog_panel_width" />
<solid android:color="?androidprv:attr/colorSurface" />
diff --git a/packages/SystemUI/res/layout/volume_dialog_legacy.xml b/packages/SystemUI/res/layout/volume_dialog_legacy.xml
index 9010ab764da0..d44b6a8534f2 100644
--- a/packages/SystemUI/res/layout/volume_dialog_legacy.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_legacy.xml
@@ -93,9 +93,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/volume_background_bottom"
- android:paddingLeft="@dimen/volume_dialog_ringer_rows_padding"
- android:paddingBottom="@dimen/volume_dialog_ringer_rows_padding"
- android:paddingRight="@dimen/volume_dialog_ringer_rows_padding">
+ android:paddingBottom="@dimen/volume_dialog_ringer_rows_padding">
<com.android.keyguard.AlphaOptimizedImageButton
android:id="@+id/settings"
android:src="@drawable/horizontal_ellipsis"
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index e14008a7773b..0381811e29ed 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -831,6 +831,11 @@
<item name="android:textColor">?attr/onSurfaceVariant</item>
</style>
+ <style name="TextAppearance.QSEditTitle" >
+ <item name="android:fontFamily">"gsf-title-medium-emphasized"</item>
+ <item name="android:textColor">?attr/onSurfaceVariant</item>
+ </style>
+
<style name="QSCustomizeToolbar" parent="@*android:style/Widget.DeviceDefault.Toolbar">
<item name="android:textColor">?attr/onSurface</item>
<item name="android:elevation">10dp</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index 8ed675c61edf..6ef7de4a32b5 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -16,7 +16,10 @@
package com.android.keyguard;
+import static com.android.systemui.Flags.gsfBouncer;
+
import android.content.Context;
+import android.graphics.Typeface;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -122,6 +125,9 @@ public class EmergencyButton extends Button {
textId = com.android.internal.R.string.lockscreen_emergency_call;
}
setText(textId);
+ if (gsfBouncer()) {
+ setTypeface(Typeface.create("gsf-title-medium", Typeface.NORMAL));
+ }
} else {
setVisibility(View.GONE);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 6bcacd023c74..fcaccd27a567 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -32,6 +32,7 @@ import static androidx.constraintlayout.widget.ConstraintSet.START;
import static androidx.constraintlayout.widget.ConstraintSet.TOP;
import static androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT;
+import static com.android.systemui.Flags.gsfBouncer;
import static com.android.systemui.plugins.FalsingManager.LOW_PENALTY;
import static java.lang.Integer.max;
@@ -51,6 +52,7 @@ import android.graphics.Bitmap;
import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Rect;
+import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
@@ -1335,6 +1337,9 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
true);
mUserSwitcherViewGroup = mView.findViewById(R.id.keyguard_bouncer_user_switcher);
mUserSwitcher = mView.findViewById(R.id.user_switcher_header);
+ if (gsfBouncer()) {
+ mUserSwitcher.setTypeface(Typeface.create("gsf-label-medium", Typeface.NORMAL));
+ }
}
interface UserSwitcherCallback {
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 7fe4ec852045..ebde8a3057ce 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -15,11 +15,13 @@
*/
package com.android.keyguard;
+import static com.android.systemui.Flags.gsfBouncer;
import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
+import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.PowerManager;
@@ -158,6 +160,9 @@ public class NumPadKey extends ViewGroup implements NumPadAnimationListener {
int klondikeColor = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary)
.getDefaultColor();
mDigitText.setTextColor(textColor);
+ if (gsfBouncer()) {
+ mDigitText.setTypeface(Typeface.create("gsf-label-large-emphasized", Typeface.NORMAL));
+ }
mKlondikeText.setTextColor(klondikeColor);
if (mAnimator != null) mAnimator.reloadColors(getContext());
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index e63472684585..1176cb0523c1 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -19,6 +19,7 @@ import static android.provider.Settings.System.SHOW_BATTERY_PERCENT;
import static com.android.settingslib.flags.Flags.newStatusBarIcons;
import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.Flags.gsfQuickSettings;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -33,6 +34,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
+import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.provider.Settings;
@@ -384,6 +386,9 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver {
}
float fontHeight = mBatteryPercentView.getPaint().getFontMetricsInt(null);
mBatteryPercentView.setLineHeight(TypedValue.COMPLEX_UNIT_PX, fontHeight);
+ if (gsfQuickSettings()) {
+ mBatteryPercentView.setTypeface(Typeface.create("gsf-label-large", Typeface.NORMAL));
+ }
if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
addView(mBatteryPercentView, new LayoutParams(
LayoutParams.WRAP_CONTENT,
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt
index 79a11ee88826..ad49fd03c577 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/BouncerMessageView.kt
@@ -17,11 +17,13 @@
package com.android.systemui.bouncer.ui
import android.content.Context
+import android.graphics.Typeface
import android.util.AttributeSet
import android.widget.LinearLayout
import com.android.keyguard.BouncerKeyguardMessageArea
import com.android.keyguard.KeyguardMessageArea
import com.android.keyguard.KeyguardMessageAreaController
+import com.android.systemui.Flags
import com.android.systemui.res.R
class BouncerMessageView : LinearLayout {
@@ -37,10 +39,20 @@ class BouncerMessageView : LinearLayout {
var secondaryMessageView: BouncerKeyguardMessageArea? = null
var primaryMessage: KeyguardMessageAreaController<KeyguardMessageArea>? = null
var secondaryMessage: KeyguardMessageAreaController<KeyguardMessageArea>? = null
+
override fun onFinishInflate() {
super.onFinishInflate()
primaryMessageView = findViewById(R.id.bouncer_primary_message_area)
secondaryMessageView = findViewById(R.id.bouncer_secondary_message_area)
+
+ if (Flags.gsfBouncer()) {
+ primaryMessageView?.apply {
+ typeface = Typeface.create("gsf-title-large-emphasized", Typeface.NORMAL)
+ }
+ secondaryMessageView?.apply {
+ typeface = Typeface.create("gsf-title-medium-emphasized", Typeface.NORMAL)
+ }
+ }
}
fun init(factory: KeyguardMessageAreaController.Factory) {
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
index ccd953de7d03..5bad9fc9c5d7 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
@@ -16,6 +16,7 @@
package com.android.systemui.brightness.ui.compose
+import android.view.MotionEvent
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.Orientation
@@ -41,6 +42,7 @@ import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
@@ -221,7 +223,16 @@ fun BrightnessSliderContainer(
)
.then(if (viewModel.showMirror) Modifier.drawInOverlay() else Modifier)
.sliderBackground(containerColor)
- .fillMaxWidth(),
+ .fillMaxWidth()
+ .pointerInteropFilter {
+ if (
+ it.actionMasked == MotionEvent.ACTION_UP ||
+ it.actionMasked == MotionEvent.ACTION_CANCEL
+ ) {
+ viewModel.emitBrightnessTouchForFalsing()
+ }
+ false
+ },
formatter = viewModel::formatValue,
hapticsViewModelFactory = viewModel.hapticsViewModelFactory,
)
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
index 1630ee58449f..7df71550d43d 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
@@ -16,12 +16,14 @@
package com.android.systemui.brightness.ui.viewmodel
-import androidx.compose.runtime.getValue
import android.content.Context
import androidx.annotation.StringRes
+import androidx.compose.runtime.getValue
import com.android.systemui.brightness.domain.interactor.BrightnessPolicyEnforcementInteractor
import com.android.systemui.brightness.domain.interactor.ScreenBrightnessInteractor
import com.android.systemui.brightness.shared.model.GammaBrightness
+import com.android.systemui.classifier.Classifier
+import com.android.systemui.classifier.domain.interactor.FalsingInteractor
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
@@ -52,6 +54,7 @@ constructor(
private val brightnessPolicyEnforcementInteractor: BrightnessPolicyEnforcementInteractor,
val hapticsViewModelFactory: SliderHapticsViewModel.Factory,
private val brightnessMirrorShowingInteractor: BrightnessMirrorShowingInteractor,
+ private val falsingInteractor: FalsingInteractor,
@Assisted private val supportsMirroring: Boolean,
private val brightnessWarningToast: BrightnessWarningToast,
) : ExclusiveActivatable() {
@@ -87,6 +90,10 @@ constructor(
brightnessWarningToast.show(viewContext, resId)
}
+ fun emitBrightnessTouchForFalsing() {
+ falsingInteractor.isFalseTouch(Classifier.BRIGHTNESS_SLIDER)
+ }
+
/**
* As a brightness slider is dragged, the corresponding events should be sent using this method.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt b/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt
index 57e9ade30bb5..074b64e0fab0 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/classifier/domain/interactor/FalsingInteractor.kt
@@ -23,6 +23,7 @@ import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.classifier.FalsingCollectorActual
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.FalsingManager.Penalty
import javax.inject.Inject
/**
@@ -63,12 +64,13 @@ constructor(
* Inserts the given [result] into the falsing system, affecting future runs of the classifier
* as if this was a result that had organically happened before.
*/
- fun updateFalseConfidence(
- result: FalsingClassifier.Result,
- ) = collector.updateFalseConfidence(result)
+ fun updateFalseConfidence(result: FalsingClassifier.Result) =
+ collector.updateFalseConfidence(result)
/** Returns `true` if the gesture should be rejected. */
- fun isFalseTouch(
- @Classifier.InteractionType interactionType: Int,
- ): Boolean = manager.isFalseTouch(interactionType)
+ fun isFalseTouch(@Classifier.InteractionType interactionType: Int): Boolean =
+ manager.isFalseTouch(interactionType)
+
+ /** Returns `true` if the tap gesture should be rejected */
+ fun isFalseTap(@Penalty penalty: Int): Boolean = manager.isFalseTap(penalty)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
index db9a7f5e81ae..d648b9c6442b 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/CommunalSceneStartable.kt
@@ -23,6 +23,7 @@ import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionKey
import com.android.internal.logging.UiEventLogger
import com.android.systemui.CoreStartable
+import com.android.systemui.Flags.communalHubOnMobile
import com.android.systemui.Flags.communalSceneKtfRefactor
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
@@ -216,6 +217,9 @@ constructor(
communalSceneInteractor.changeScene(
newScene = CommunalScenes.Blank,
loggingReason = "hub timeout",
+ transitionKey =
+ if (communalHubOnMobile()) CommunalTransitionKeys.SimpleFade
+ else null,
)
uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_TIMEOUT)
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 7b91eaecd33a..38cfb9b333a8 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -25,6 +25,8 @@ import com.android.systemui.back.domain.interactor.BackActionInteractor
import com.android.systemui.biometrics.BiometricNotificationService
import com.android.systemui.bouncer.domain.startable.BouncerStartable
import com.android.systemui.clipboardoverlay.ClipboardListener
+import com.android.systemui.complication.ComplicationTypesUpdater
+import com.android.systemui.complication.DreamClockTimeComplication
import com.android.systemui.controls.dagger.StartControlsStartableModule
import com.android.systemui.dagger.qualifiers.PerUser
import com.android.systemui.dreams.AssistantAttentionMonitor
@@ -337,4 +339,18 @@ abstract class SystemUICoreStartableModule {
abstract fun bindDreamOverlayRegistrant(
dreamOverlayRegistrant: DreamOverlayRegistrant
): CoreStartable
+
+ /** Inject into DreamClockTimeComplication.Registrant */
+ @Binds
+ @IntoMap
+ @ClassKey(DreamClockTimeComplication.Registrant::class)
+ abstract fun bindDreamClockTimeComplicationRegistrant(
+ registrant: DreamClockTimeComplication.Registrant
+ ): CoreStartable
+
+ /** Inject into ComplicationTypesUpdater. */
+ @Binds
+ @IntoMap
+ @ClassKey(ComplicationTypesUpdater::class)
+ abstract fun bindComplicationTypesUpdater(updater: ComplicationTypesUpdater): CoreStartable
}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
index 400d09742d13..2e1096fcae36 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
@@ -84,30 +84,53 @@ constructor(
)
/**
+ * Emits `true` when the current scene switches to [Scenes.Gone] for the first time after having
+ * been on [Scenes.Lockscreen].
+ *
+ * Different from [isDeviceEntered] such that the current scene must actually go through
+ * [Scenes.Gone] to produce a `true`. [isDeviceEntered] also takes into account the navigation
+ * back stack and will produce a `true` value even when the current scene is still not
+ * [Scenes.Gone] but the bottommost entry of the navigation back stack switched from
+ * [Scenes.Lockscreen] to [Scenes.Gone] while the user is staring at another scene.
+ */
+ val isDeviceEnteredDirectly: StateFlow<Boolean> =
+ sceneInteractor.currentScene
+ .filter { currentScene ->
+ currentScene == Scenes.Gone || currentScene == Scenes.Lockscreen
+ }
+ .mapLatestConflated { scene ->
+ if (scene == Scenes.Gone) {
+ // Make sure device unlock status is definitely unlocked before we
+ // consider the device "entered".
+ deviceUnlockedInteractor.deviceUnlockStatus.first { it.isUnlocked }
+ true
+ } else {
+ false
+ }
+ }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.Eagerly,
+ initialValue = false,
+ )
+
+ /**
* Whether the device has been entered (i.e. the lockscreen has been dismissed, by any method).
* This can be `false` when the device is unlocked, e.g. when the user still needs to swipe away
* the non-secure lockscreen, even though they've already authenticated.
*
* Note: This does not imply that the lockscreen is visible or not.
+ *
+ * Different from [isDeviceEnteredDirectly] such that the current scene doesn't actually have to
+ * go through [Scenes.Gone] to produce a `true`. [isDeviceEnteredDirectly] doesn't take the
+ * navigation back stack into account and will only produce a `true` value even when the current
+ * scene is actually [Scenes.Gone].
*/
val isDeviceEntered: StateFlow<Boolean> =
combine(
// This flow emits true when the currentScene switches to Gone for the first time
// after having been on Lockscreen.
- sceneInteractor.currentScene
- .filter { currentScene ->
- currentScene == Scenes.Gone || currentScene == Scenes.Lockscreen
- }
- .mapLatestConflated { scene ->
- if (scene == Scenes.Gone) {
- // Make sure device unlock status is definitely unlocked before we
- // consider the device "entered".
- deviceUnlockedInteractor.deviceUnlockStatus.first { it.isUnlocked }
- true
- } else {
- false
- }
- },
+ isDeviceEnteredDirectly,
// This flow emits true only if the bottom of the navigation back stack has been
// switched from Lockscreen to Gone. In other words, only if the device was unlocked
// while visiting at least one scene "above" the Lockscreen scene.
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 408fe831d74c..43b7cedcd767 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -18,6 +18,7 @@ package com.android.systemui.dreams;
import static android.service.dreams.Flags.dreamWakeRedirect;
+import static com.android.systemui.Flags.communalHubOnMobile;
import static com.android.systemui.Flags.glanceableHubAllowKeyguardWhenDreaming;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_WINDOW_TITLE;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_TOUCH_INSET_MANAGER;
@@ -54,12 +55,14 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.PhoneWindow;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.ambient.touch.TouchHandler;
import com.android.systemui.ambient.touch.TouchMonitor;
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent;
import com.android.systemui.ambient.touch.scrim.ScrimManager;
import com.android.systemui.communal.domain.interactor.CommunalInteractor;
import com.android.systemui.communal.shared.log.CommunalUiEvent;
import com.android.systemui.communal.shared.model.CommunalScenes;
+import com.android.systemui.communal.shared.model.CommunalTransitionKeys;
import com.android.systemui.complication.dagger.ComplicationComponent;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.dagger.DreamOverlayComponent;
@@ -76,8 +79,8 @@ import com.android.systemui.util.concurrency.DelayableExecutor;
import kotlinx.coroutines.Job;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashSet;
+import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.function.Consumer;
@@ -483,11 +486,16 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
final DreamOverlayComponent dreamOverlayComponent = mDreamOverlayComponentFactory.create(
mLifecycleOwner, complicationComponent.getComplicationHostViewController(),
mTouchInsetManager);
+
+ final ArrayList<TouchHandler> touchHandlers = new ArrayList<>(
+ List.of(dreamComplicationComponent.getHideComplicationTouchHandler()));
+ if (!communalHubOnMobile()) {
+ // Do not add the communal touch handler for glanceable hub v2 since there is no dream
+ // to hub swipe gesture.
+ touchHandlers.add(dreamOverlayComponent.getCommunalTouchHandler());
+ }
final AmbientTouchComponent ambientTouchComponent = mAmbientTouchComponentFactory.create(
- mLifecycleOwner,
- new HashSet<>(Arrays.asList(
- dreamComplicationComponent.getHideComplicationTouchHandler(),
- dreamOverlayComponent.getCommunalTouchHandler())), TAG);
+ mLifecycleOwner, new HashSet<>(touchHandlers), TAG);
setLifecycleStateLocked(Lifecycle.State.STARTED);
@@ -568,7 +576,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
} else {
mCommunalInteractor.changeScene(CommunalScenes.Communal,
"dream wake requested",
- null);
+ communalHubOnMobile() ? CommunalTransitionKeys.INSTANCE.getSimpleFade() : null);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
index b37206a4fef7..160574fa2244 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModel.kt
@@ -19,6 +19,7 @@ package com.android.systemui.dreams.ui.viewmodel
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
@@ -38,6 +39,7 @@ import kotlinx.coroutines.flow.map
class DreamUserActionsViewModel
@AssistedInject
constructor(
+ private val communalInteractor: CommunalInteractor,
private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
private val shadeInteractor: ShadeInteractor,
) : UserActionsViewModel() {
@@ -50,10 +52,13 @@ constructor(
} else {
combine(
deviceUnlockedInteractor.deviceUnlockStatus.map { it.isUnlocked },
+ communalInteractor.isCommunalAvailable,
shadeInteractor.shadeMode,
- ) { isDeviceUnlocked, shadeMode ->
+ ) { isDeviceUnlocked, isCommunalAvailable, shadeMode ->
buildList {
- add(Swipe.Start to Scenes.Communal)
+ if (isCommunalAvailable) {
+ add(Swipe.Start to Scenes.Communal)
+ }
val bouncerOrGone =
if (isDeviceUnlocked) Scenes.Gone else Scenes.Bouncer
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
index 092a25aa1cad..7bd09b915d1a 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt
@@ -20,6 +20,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
+import android.os.Build
import android.os.UserHandle
import com.android.systemui.CoreStartable
import com.android.systemui.broadcast.BroadcastDispatcher
@@ -52,13 +53,13 @@ constructor(
receiver =
object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
- applicationContext.startActivityAsUser(
- Intent(
- applicationContext,
- KeyboardTouchpadTutorialActivity::class.java
- ),
- UserHandle.SYSTEM
- )
+ val activityIntent =
+ Intent(applicationContext, KeyboardTouchpadTutorialActivity::class.java)
+ if (Build.IS_DEBUGGABLE) {
+ // helpful for testing different cases but pointless for public builds
+ intent.extras?.let { activityIntent.putExtras(it) }
+ }
+ applicationContext.startActivityAsUser(activityIntent, UserHandle.SYSTEM)
}
},
filter = IntentFilter("com.android.systemui.action.KEYBOARD_TOUCHPAD_TUTORIAL"),
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialMetricsLogger.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialMetricsLogger.kt
index 144c5ead1bb8..ae6cbbc4315e 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialMetricsLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialMetricsLogger.kt
@@ -18,8 +18,8 @@ package com.android.systemui.inputdevice.tutorial
import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_ENTRY_POINT_CONTEXTUAL_EDU
import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEYBOARD
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD
import com.android.systemui.shared.system.SysUiStatsLog
import javax.inject.Inject
@@ -37,9 +37,9 @@ class KeyboardTouchpadTutorialMetricsLogger @Inject constructor() {
val tutorialType =
when (tutorialTypeExtra) {
- INTENT_TUTORIAL_TYPE_KEYBOARD ->
+ INTENT_TUTORIAL_SCOPE_KEYBOARD ->
SysUiStatsLog.PERIPHERAL_TUTORIAL_LAUNCHED__TUTORIAL_TYPE__KEYBOARD
- INTENT_TUTORIAL_TYPE_TOUCHPAD ->
+ INTENT_TUTORIAL_SCOPE_TOUCHPAD ->
SysUiStatsLog.PERIPHERAL_TUTORIAL_LAUNCHED__TUTORIAL_TYPE__TOUCHPAD
else -> SysUiStatsLog.PERIPHERAL_TUTORIAL_LAUNCHED__TUTORIAL_TYPE__BOTH
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt
index 9dae64921d26..3cba70e39e66 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/TutorialNotificationCoordinator.kt
@@ -34,10 +34,10 @@ import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSched
import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity
import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_ENTRY_POINT_KEY
import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_BOTH
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEY
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEYBOARD
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_ALL
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEY
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD
import com.android.systemui.res.R
import com.android.systemui.settings.UserTracker
import javax.inject.Inject
@@ -108,7 +108,7 @@ constructor(
private fun createPendingIntent(tutorialType: String): PendingIntent {
val intent =
Intent(context, KeyboardTouchpadTutorialActivity::class.java).apply {
- putExtra(INTENT_TUTORIAL_TYPE_KEY, tutorialType)
+ putExtra(INTENT_TUTORIAL_SCOPE_KEY, tutorialType)
putExtra(INTENT_TUTORIAL_ENTRY_POINT_KEY, INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
@@ -128,13 +128,13 @@ constructor(
NotificationInfo(
context.getString(R.string.launch_keyboard_tutorial_notification_title),
context.getString(R.string.launch_keyboard_tutorial_notification_content),
- INTENT_TUTORIAL_TYPE_KEYBOARD,
+ INTENT_TUTORIAL_SCOPE_KEYBOARD,
)
TutorialType.TOUCHPAD ->
NotificationInfo(
context.getString(R.string.launch_touchpad_tutorial_notification_title),
context.getString(R.string.launch_touchpad_tutorial_notification_content),
- INTENT_TUTORIAL_TYPE_TOUCHPAD,
+ INTENT_TUTORIAL_SCOPE_TOUCHPAD,
)
TutorialType.BOTH ->
NotificationInfo(
@@ -144,7 +144,7 @@ constructor(
context.getString(
R.string.launch_keyboard_touchpad_tutorial_notification_content
),
- INTENT_TUTORIAL_TYPE_BOTH,
+ INTENT_TUTORIAL_SCOPE_ALL,
)
TutorialType.NONE -> null
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
index fee08b31bd93..67b307fb7a36 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/view/KeyboardTouchpadTutorialActivity.kt
@@ -56,10 +56,13 @@ constructor(
) : ComponentActivity() {
companion object {
- const val INTENT_TUTORIAL_TYPE_KEY = "tutorial_type"
- const val INTENT_TUTORIAL_TYPE_TOUCHPAD = "touchpad"
- const val INTENT_TUTORIAL_TYPE_KEYBOARD = "keyboard"
- const val INTENT_TUTORIAL_TYPE_BOTH = "both"
+ const val INTENT_TUTORIAL_SCOPE_KEY = "tutorial_scope"
+ const val INTENT_TUTORIAL_SCOPE_TOUCHPAD = "touchpad"
+ const val INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK = "touchpad_back"
+ const val INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME = "touchpad_home"
+ const val INTENT_TUTORIAL_SCOPE_KEYBOARD = "keyboard"
+ const val INTENT_TUTORIAL_SCOPE_ALL = "all"
+
const val INTENT_TUTORIAL_ENTRY_POINT_KEY = "entry_point"
const val INTENT_TUTORIAL_ENTRY_POINT_SCHEDULER = "scheduler"
const val INTENT_TUTORIAL_ENTRY_POINT_CONTEXTUAL_EDU = "contextual_edu"
@@ -94,7 +97,7 @@ constructor(
if (savedInstanceState == null) {
metricsLogger.logPeripheralTutorialLaunched(
intent.getStringExtra(INTENT_TUTORIAL_ENTRY_POINT_KEY),
- intent.getStringExtra(INTENT_TUTORIAL_TYPE_KEY),
+ intent.getStringExtra(INTENT_TUTORIAL_SCOPE_KEY),
)
logger.logOpenTutorial(TutorialContext.KEYBOARD_TOUCHPAD_TUTORIAL)
}
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
index 896bdc068154..eeb4b697a5fc 100644
--- a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/ui/viewmodel/KeyboardTouchpadTutorialViewModel.kt
@@ -22,15 +22,21 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.inputdevice.tutorial.InputDeviceTutorialLogger
import com.android.systemui.inputdevice.tutorial.domain.interactor.ConnectionState
import com.android.systemui.inputdevice.tutorial.domain.interactor.KeyboardTouchpadConnectionInteractor
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEY
-import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_TYPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_ALL
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEY
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_KEYBOARD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK
+import com.android.systemui.inputdevice.tutorial.ui.view.KeyboardTouchpadTutorialActivity.Companion.INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME
import com.android.systemui.inputdevice.tutorial.ui.viewmodel.RequiredHardware.KEYBOARD
import com.android.systemui.inputdevice.tutorial.ui.viewmodel.RequiredHardware.TOUCHPAD
import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.ACTION_KEY
import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.BACK_GESTURE
+import com.android.systemui.inputdevice.tutorial.ui.viewmodel.Screen.HOME_GESTURE
import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -42,27 +48,23 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNot
import kotlinx.coroutines.flow.runningFold
-import com.android.app.tracing.coroutines.launchTraced as launch
class KeyboardTouchpadTutorialViewModel(
private val gesturesInteractor: Optional<TouchpadGesturesInteractor>,
private val keyboardTouchpadConnectionInteractor: KeyboardTouchpadConnectionInteractor,
private val hasTouchpadTutorialScreens: Boolean,
private val logger: InputDeviceTutorialLogger,
- handle: SavedStateHandle
+ handle: SavedStateHandle,
) : ViewModel(), DefaultLifecycleObserver {
- private fun startingScreen(handle: SavedStateHandle): Screen {
- val tutorialType: String? = handle[INTENT_TUTORIAL_TYPE_KEY]
- return if (tutorialType == INTENT_TUTORIAL_TYPE_KEYBOARD) ACTION_KEY else BACK_GESTURE
- }
-
private val _screen = MutableStateFlow(startingScreen(handle))
val screen: Flow<Screen> = _screen.filter { it.canBeShown() }
private val _closeActivity: MutableStateFlow<Boolean> = MutableStateFlow(false)
val closeActivity: StateFlow<Boolean> = _closeActivity
+ private val screenSequence: ScreenSequence = chooseScreenSequence(handle)
+
private val screensBackStack = ArrayDeque(listOf(_screen.value))
private var connectionState: ConnectionState =
@@ -105,6 +107,33 @@ class KeyboardTouchpadTutorialViewModel(
}
}
+ private fun startingScreen(handle: SavedStateHandle): Screen {
+ val scope: String? = handle[INTENT_TUTORIAL_SCOPE_KEY]
+ return when (scope) {
+ INTENT_TUTORIAL_SCOPE_KEYBOARD -> ACTION_KEY
+ INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME -> HOME_GESTURE
+ INTENT_TUTORIAL_SCOPE_TOUCHPAD,
+ INTENT_TUTORIAL_SCOPE_ALL,
+ INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK -> BACK_GESTURE
+ else -> {
+ logger.w("Intent didn't specify tutorial scope, starting with default")
+ BACK_GESTURE
+ }
+ }
+ }
+
+ private fun chooseScreenSequence(handle: SavedStateHandle): ScreenSequence {
+ val scope: String? = handle[INTENT_TUTORIAL_SCOPE_KEY]
+ return if (
+ scope == INTENT_TUTORIAL_SCOPE_TOUCHPAD_HOME ||
+ scope == INTENT_TUTORIAL_SCOPE_TOUCHPAD_BACK
+ ) {
+ SingleScreenOnly
+ } else {
+ AllSupportedScreens
+ }
+ }
+
override fun onCleared() {
// this shouldn't be needed as onTutorialInvisible should already clear device state but
// it'd be really bad if we'd block gestures/shortcuts after leaving tutorial so just to be
@@ -121,13 +150,13 @@ class KeyboardTouchpadTutorialViewModel(
}
fun onDoneButtonClicked() {
- var nextScreen = _screen.value.next()
+ var nextScreen = screenSequence.nextScreen(_screen.value)
while (nextScreen != null) {
if (requiredHardwarePresent(nextScreen)) {
break
}
logger.logNextScreenMissingHardware(nextScreen)
- nextScreen = nextScreen.next()
+ nextScreen = screenSequence.nextScreen(nextScreen)
}
if (nextScreen == null) {
logger.d("Final screen reached, closing tutorial")
@@ -192,33 +221,44 @@ class KeyboardTouchpadTutorialViewModel(
override fun <T : ViewModel> create(
key: String,
modelClass: Class<T>,
- handle: SavedStateHandle
+ handle: SavedStateHandle,
): T =
KeyboardTouchpadTutorialViewModel(
gesturesInteractor,
keyboardTouchpadConnected,
hasTouchpadTutorialScreens,
logger,
- handle
+ handle,
)
as T
}
+
+ private interface ScreenSequence {
+ fun nextScreen(current: Screen): Screen?
+ }
+
+ private object AllSupportedScreens : ScreenSequence {
+ override fun nextScreen(current: Screen): Screen? {
+ return when (current) {
+ BACK_GESTURE -> HOME_GESTURE
+ HOME_GESTURE -> ACTION_KEY
+ ACTION_KEY -> null
+ }
+ }
+ }
+
+ private object SingleScreenOnly : ScreenSequence {
+ override fun nextScreen(current: Screen): Screen? = null
+ }
}
enum class RequiredHardware {
TOUCHPAD,
- KEYBOARD
+ KEYBOARD,
}
enum class Screen(val requiredHardware: RequiredHardware) {
BACK_GESTURE(requiredHardware = TOUCHPAD),
HOME_GESTURE(requiredHardware = TOUCHPAD),
- ACTION_KEY(requiredHardware = KEYBOARD);
-
- fun next(): Screen? =
- when (this) {
- BACK_GESTURE -> HOME_GESTURE
- HOME_GESTURE -> ACTION_KEY
- ACTION_KEY -> null
- }
+ ACTION_KEY(requiredHardware = KEYBOARD),
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt
index 99cafd3daacb..321fd57d3e8b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/CustomShortcutCategoriesRepository.kt
@@ -28,6 +28,7 @@ import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_RES
import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS
import android.hardware.input.InputSettings
import android.hardware.input.KeyGestureEvent
+import android.hardware.input.KeyGestureEvent.KeyGestureType
import android.util.Log
import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.mutableStateOf
@@ -44,6 +45,8 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomization
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.settings.UserTracker
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -52,8 +55,6 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
-import javax.inject.Inject
-import kotlin.coroutines.CoroutineContext
@SysUISingleton
class CustomShortcutCategoriesRepository
@@ -65,7 +66,7 @@ constructor(
@Background private val bgCoroutineContext: CoroutineContext,
private val shortcutCategoriesUtils: ShortcutCategoriesUtils,
private val context: Context,
- private val inputGestureMaps: InputGestureMaps
+ private val inputGestureMaps: InputGestureMaps,
) : ShortcutCategoriesRepository {
private val userContext: Context
@@ -130,9 +131,7 @@ constructor(
emptyList()
} else {
val customInputGesturesForUser: List<InputGestureData> =
- if (InputSettings.isCustomizableInputGesturesFeatureFlagEnabled()) {
- inputManager.getCustomInputGestures(/* filter= */ null)
- } else emptyList()
+ getCustomInputGestures()
val sources = toInternalGroupSources(customInputGesturesForUser)
val supportedKeyCodes =
shortcutCategoriesUtils.fetchSupportedKeyCodes(
@@ -173,16 +172,20 @@ constructor(
.addKeyGestureTypeFromShortcutLabel()
.addTriggerFromSelectedKeyCombination()
.build()
- // TODO(b/379648200) add app launch data for application categories shortcut after
- // dynamic
- // label/icon mapping implementation
+ // TODO(b/379648200) add app launch data after dynamic label/icon mapping implementation
} catch (e: IllegalArgumentException) {
Log.w(TAG, "could not add custom shortcut: $e")
return null
}
}
- suspend fun confirmAndSetShortcutCurrentlyBeingCustomized(): ShortcutCustomizationRequestResult {
+ private fun retrieveInputGestureDataForShortcutBeingDeleted(): InputGestureData? {
+ val keyGestureType = getKeyGestureTypeFromShortcutBeingDeletedLabel()
+ return getCustomInputGestures().firstOrNull { it.action.keyGestureType() == keyGestureType }
+ }
+
+ suspend fun confirmAndSetShortcutCurrentlyBeingCustomized():
+ ShortcutCustomizationRequestResult {
return withContext(bgCoroutineContext) {
val inputGestureData =
buildInputGestureDataForShortcutBeingCustomized()
@@ -201,24 +204,79 @@ constructor(
}
}
+ suspend fun deleteShortcutCurrentlyBeingCustomized():
+ ShortcutCustomizationRequestResult {
+ return withContext(bgCoroutineContext) {
+ val inputGestureData =
+ retrieveInputGestureDataForShortcutBeingDeleted()
+ ?: return@withContext ShortcutCustomizationRequestResult.ERROR_OTHER
+ return@withContext when (
+ val result = inputManager.removeCustomInputGesture(inputGestureData)
+ ) {
+ CUSTOM_INPUT_GESTURE_RESULT_SUCCESS -> ShortcutCustomizationRequestResult.SUCCESS
+ else -> {
+ Log.w(
+ TAG,
+ "Attempted to delete shortcut being customized " +
+ "${_shortcutBeingCustomized.value} but ran into an error. InputGestureData" +
+ " = $inputGestureData, error code: $result",
+ )
+ ShortcutCustomizationRequestResult.ERROR_OTHER
+ }
+ }
+ }
+ }
+
+ private fun getCustomInputGestures(): List<InputGestureData> {
+ return if (InputSettings.isCustomizableInputGesturesFeatureFlagEnabled()) {
+ inputManager.getCustomInputGestures(/* filter= */ InputGestureData.Filter.KEY)
+ } else emptyList()
+ }
+
private fun Builder.addKeyGestureTypeFromShortcutLabel(): Builder {
+ val keyGestureType = getKeyGestureTypeFromShortcutBeingCustomizedLabel()
+
+ if (keyGestureType == null) {
+ Log.w(
+ TAG,
+ "Could not find KeyGestureType for shortcut ${_shortcutBeingCustomized.value}",
+ )
+ return this
+ }
+
+ return setKeyGestureType(keyGestureType)
+ }
+
+ @KeyGestureType
+ private fun getKeyGestureTypeFromShortcutBeingCustomizedLabel(): Int? {
val shortcutBeingCustomized =
getShortcutBeingCustomized() as? ShortcutCustomizationRequestInfo.Add
if (shortcutBeingCustomized == null) {
- Log.w(TAG, "User requested to set shortcut but shortcut being customized is null")
- return this
+ Log.w(
+ TAG,
+ "Requested key gesture type from label but shortcut being customized is null",
+ )
+ return null
}
- val keyGestureType =
- inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label]
+ return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label]
+ }
- if (keyGestureType == null) {
- Log.w(TAG, "Could not find KeyGestureType for shortcut $shortcutBeingCustomized")
- return this
+ @KeyGestureType
+ private fun getKeyGestureTypeFromShortcutBeingDeletedLabel(): Int? {
+ val shortcutBeingCustomized =
+ getShortcutBeingCustomized() as? ShortcutCustomizationRequestInfo.Delete
+
+ if (shortcutBeingCustomized == null) {
+ Log.w(
+ TAG,
+ "Requested key gesture type from label but shortcut being customized is null",
+ )
+ return null
}
- return setKeyGestureType(keyGestureType)
+ return inputGestureMaps.shortcutLabelToKeyGestureTypeMap[shortcutBeingCustomized.label]
}
private fun Builder.addTriggerFromSelectedKeyCombination(): Builder {
@@ -227,7 +285,7 @@ constructor(
Log.w(
TAG,
"User requested to set shortcut but selected key combination is " +
- "$selectedKeyCombination",
+ "$selectedKeyCombination",
)
return this
}
@@ -235,8 +293,7 @@ constructor(
return setTrigger(
createKeyTrigger(
/* keycode = */ selectedKeyCombination.keyCode,
- /* modifierState = */
- shortcutCategoriesUtils.removeUnsupportedModifiers(
+ /* modifierState = */ shortcutCategoriesUtils.removeUnsupportedModifiers(
selectedKeyCombination.modifiers
),
)
@@ -256,10 +313,8 @@ constructor(
val keyTrigger = gestureData.trigger as KeyTrigger
val keyGestureType = gestureData.action.keyGestureType()
fetchGroupLabelByGestureType(keyGestureType)?.let { groupLabel ->
- toInternalKeyboardShortcutInfo(
- keyGestureType,
- keyTrigger
- )?.let { internalKeyboardShortcutInfo ->
+ toInternalKeyboardShortcutInfo(keyGestureType, keyTrigger)?.let {
+ internalKeyboardShortcutInfo ->
val group =
InternalKeyboardShortcutGroup(
label = groupLabel,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
index d228a15e51b4..ecc076178d2d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/InputGestureMaps.kt
@@ -48,9 +48,7 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.
import com.android.systemui.res.R
import javax.inject.Inject
-class InputGestureMaps
-@Inject
-constructor(private val context: Context) {
+class InputGestureMaps @Inject constructor(private val context: Context) {
val gestureToShortcutCategoryTypeMap =
mapOf(
// System Category
@@ -180,9 +178,10 @@ constructor(private val context: Context) {
)
val shortcutLabelToKeyGestureTypeMap: Map<String, Int>
- get() = gestureToInternalKeyboardShortcutInfoLabelResIdMap.entries.associateBy({
- context.getString(it.value)
- }) {
- it.key
- }
+ get() =
+ gestureToInternalKeyboardShortcutInfoLabelResIdMap.entries.associateBy({
+ context.getString(it.value)
+ }) {
+ it.key
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
index 95bc9f66618c..a0897f293624 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutCategoriesUtils.kt
@@ -36,9 +36,9 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
-import kotlinx.coroutines.withContext
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.withContext
class ShortcutCategoriesUtils
@Inject
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
index f4e2f05379bb..7743c53c6900 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutCustomizationInteractor.kt
@@ -41,7 +41,13 @@ constructor(private val customShortcutRepository: CustomShortcutCategoriesReposi
customShortcutRepository.onCustomizationRequested(requestInfo)
}
- suspend fun confirmAndSetShortcutCurrentlyBeingCustomized(): ShortcutCustomizationRequestResult {
+ suspend fun confirmAndSetShortcutCurrentlyBeingCustomized():
+ ShortcutCustomizationRequestResult {
return customShortcutRepository.confirmAndSetShortcutCurrentlyBeingCustomized()
}
+
+ suspend fun deleteShortcutCurrentlyBeingCustomized():
+ ShortcutCustomizationRequestResult {
+ return customShortcutRepository.deleteShortcutCurrentlyBeingCustomized()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
index 813a1fcac65d..464805334c2a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
@@ -18,25 +18,31 @@ package com.android.systemui.keyboard.shortcut.shared.model
sealed interface ShortcutCategoryType {
val isTrusted: Boolean
+ val includeInCustomization: Boolean
data object System : ShortcutCategoryType {
override val isTrusted: Boolean = true
+ override val includeInCustomization: Boolean = true
}
data object MultiTasking : ShortcutCategoryType {
override val isTrusted: Boolean = true
+ override val includeInCustomization: Boolean = true
}
data object InputMethodEditor : ShortcutCategoryType {
override val isTrusted: Boolean = false
+ override val includeInCustomization: Boolean = false
}
data object AppCategories : ShortcutCategoryType {
override val isTrusted: Boolean = true
+ override val includeInCustomization: Boolean = true
}
data class CurrentApp(val packageName: String) : ShortcutCategoryType {
override val isTrusted: Boolean = false
+ override val includeInCustomization: Boolean = false
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
index 67caadba0d45..f28618bb8cf4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
@@ -73,22 +73,17 @@ constructor(
return dialogFactory.create(dialogDelegate = ShortcutCustomizationDialogDelegate()) { dialog
->
val uiState by
- viewModel.shortcutCustomizationUiState.collectAsStateWithLifecycle(
- initialValue = ShortcutCustomizationUiState.Inactive
- )
+ viewModel.shortcutCustomizationUiState.collectAsStateWithLifecycle(
+ initialValue = ShortcutCustomizationUiState.Inactive
+ )
val coroutineScope = rememberCoroutineScope()
ShortcutCustomizationDialog(
uiState = uiState,
- modifier = Modifier
- .width(364.dp)
- .wrapContentHeight()
- .padding(vertical = 24.dp),
+ modifier = Modifier.width(364.dp).wrapContentHeight().padding(vertical = 24.dp),
onKeyPress = { viewModel.onKeyPressed(it) },
onCancel = { dialog.dismiss() },
- onConfirmSetShortcut = {
- coroutineScope.launch { viewModel.onSetShortcut() }
- },
- onConfirmDeleteShortcut = { viewModel.onDeleteShortcut() },
+ onConfirmSetShortcut = { coroutineScope.launch { viewModel.onSetShortcut() } },
+ onConfirmDeleteShortcut = { coroutineScope.launch { viewModel.deleteShortcutCurrentlyBeingCustomized() } },
)
dialog.setOnDismissListener { viewModel.onDialogDismissed() }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
index cd13e87029f6..e3675de5d197 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
@@ -461,7 +461,7 @@ private fun EndSidePanel(
SubCategoryContainerDualPane(
searchQuery = searchQuery,
subCategory = subcategory,
- isCustomizing = isCustomizing,
+ isCustomizing = isCustomizing and category.type.includeInCustomization,
onCustomizationRequested = { requestInfo ->
when (requestInfo) {
is ShortcutCustomizationRequestInfo.Add ->
@@ -786,7 +786,7 @@ private fun ShortcutDescriptionText(
Text(
modifier = modifier,
text = textWithHighlightedSearchQuery(shortcut.label, searchQuery),
- style = MaterialTheme.typography.bodyMedium,
+ style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.onSurface,
)
}
@@ -904,7 +904,7 @@ private fun CategoryItemTwoPane(
Text(
fontSize = 18.sp,
color = colors.textColor(selected).value,
- style = MaterialTheme.typography.headlineSmall,
+ style = MaterialTheme.typography.titleSmall,
text = label,
)
}
@@ -1000,9 +1000,11 @@ private fun KeyboardSettings(horizontalPadding: Dp, verticalPadding: Dp, onClick
) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
- stringResource(id = R.string.shortcut_helper_keyboard_settings_buttons_label),
+ text =
+ stringResource(id = R.string.shortcut_helper_keyboard_settings_buttons_label),
color = MaterialTheme.colorScheme.onSurfaceVariant,
fontSize = 16.sp,
+ style = MaterialTheme.typography.titleSmall,
)
Spacer(modifier = Modifier.weight(1f))
Icon(
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
index 869682742043..b467bb481443 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
@@ -79,8 +79,7 @@ constructor(
}
is ShortcutCustomizationRequestInfo.Delete -> {
- _shortcutCustomizationUiState.value =
- DeleteShortcutDialog(isDialogShowing = false)
+ _shortcutCustomizationUiState.value = DeleteShortcutDialog(isDialogShowing = false)
shortcutCustomizationInteractor.onCustomizationRequested(requestInfo)
}
}
@@ -134,17 +133,23 @@ constructor(
}
}
- fun onDeleteShortcut() {
- // TODO(b/373631984) not yet implemented
+ suspend fun deleteShortcutCurrentlyBeingCustomized() {
+ val result =
+ shortcutCustomizationInteractor.deleteShortcutCurrentlyBeingCustomized()
+
+ _shortcutCustomizationUiState.update { uiState ->
+ when (result) {
+ ShortcutCustomizationRequestResult.SUCCESS -> ShortcutCustomizationUiState.Inactive
+ else -> uiState
+ }
+ }
}
private fun getUiStateWithErrorMessage(
uiState: ShortcutCustomizationUiState,
errorMessage: String,
): ShortcutCustomizationUiState {
- return (uiState as? AddShortcutDialog)?.copy(
- errorMessage = errorMessage
- ) ?: uiState
+ return (uiState as? AddShortcutDialog)?.copy(errorMessage = errorMessage) ?: uiState
}
private fun updatePressedKeys(keyEvent: KeyEvent) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
index 0b78be128c69..8906156252a6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
@@ -25,6 +25,7 @@ import com.android.systemui.common.shared.model.Icon
import com.android.systemui.communal.data.repository.CommunalSceneRepository
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.communal.shared.model.CommunalTransitionKeys
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.res.R
@@ -98,7 +99,10 @@ constructor(
if (SceneContainerFlag.isEnabled) {
sceneInteractor.changeScene(Scenes.Communal, "lockscreen to communal from shortcut")
} else {
- communalSceneRepository.changeScene(CommunalScenes.Communal, null)
+ communalSceneRepository.changeScene(
+ CommunalScenes.Communal,
+ transitionKey = CommunalTransitionKeys.SimpleFade,
+ )
}
return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index 1e672e23970b..deef2a6c3a4c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -21,11 +21,13 @@ import android.annotation.SuppressLint
import android.app.DreamManager
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.systemui.Flags.communalHubOnMobile
import com.android.systemui.Flags.communalSceneKtfRefactor
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.communal.shared.model.CommunalTransitionKeys
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -48,7 +50,6 @@ import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.filter
-import com.android.app.tracing.coroutines.launchTraced as launch
@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
@@ -176,6 +177,9 @@ constructor(
communalSceneInteractor.changeScene(
newScene = CommunalScenes.Communal,
loggingReason = "FromDreamingTransitionInteractor",
+ transitionKey =
+ if (communalHubOnMobile()) CommunalTransitionKeys.SimpleFade
+ else null,
)
} else {
startTransitionTo(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
index 364b1a9731cc..9df293bf2c15 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
@@ -112,8 +112,10 @@ constructor(
}
.distinctUntilChanged()
- private val isDeviceEntered by lazy { deviceEntryInteractor.get().isDeviceEntered }
- private val isDeviceNotEntered by lazy { isDeviceEntered.map { !it } }
+ private val isDeviceEnteredDirectly by lazy {
+ deviceEntryInteractor.get().isDeviceEnteredDirectly
+ }
+ private val isDeviceNotEnteredDirectly by lazy { isDeviceEnteredDirectly.map { !it } }
/**
* Surface visibility, which is either determined by the default visibility when not
@@ -126,7 +128,7 @@ constructor(
sceneInteractor.get().transitionState.flatMapLatestConflated { state ->
when {
state.isTransitioning(from = Scenes.Lockscreen, to = Scenes.Gone) ->
- isDeviceEntered
+ isDeviceEnteredDirectly
state.isTransitioning(from = Scenes.Bouncer, to = Scenes.Gone) ->
(state as Transition).progress.map { progress ->
progress >
@@ -210,7 +212,7 @@ constructor(
when (it.currentScene) {
in keyguardScenes -> flowOf(true)
in nonKeyguardScenes -> flowOf(false)
- in keyguardAgnosticScenes -> isDeviceNotEntered
+ in keyguardAgnosticScenes -> isDeviceNotEnteredDirectly
else ->
throw IllegalStateException("Unknown scene: ${it.currentScene}")
}
@@ -220,7 +222,7 @@ constructor(
it.isTransitioningSets(from = keyguardScenes) -> flowOf(true)
it.isTransitioningSets(from = nonKeyguardScenes) -> flowOf(false)
it.isTransitioningSets(from = keyguardAgnosticScenes) ->
- isDeviceNotEntered
+ isDeviceNotEnteredDirectly
else ->
throw IllegalStateException("Unknown scene: ${it.fromContent}")
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
index 6c03b2489380..ac302dd26365 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
@@ -17,7 +17,7 @@
package com.android.systemui.keyguard.ui.binder
-import android.content.Context
+import android.content.res.Resources
import android.view.View
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
@@ -34,8 +34,8 @@ import com.android.systemui.keyguard.ui.view.layout.sections.setVisibility
import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewClockViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.plugins.clocks.ClockPreviewConfig
import com.android.systemui.shared.clocks.ClockRegistry
-import kotlin.reflect.KSuspendFunction1
/** Binder for the small clock view, large clock view. */
object KeyguardPreviewClockViewBinder {
@@ -66,11 +66,11 @@ object KeyguardPreviewClockViewBinder {
@JvmStatic
fun bind(
- context: Context,
rootView: ConstraintLayout,
viewModel: KeyguardPreviewClockViewModel,
clockRegistry: ClockRegistry,
- updateClockAppearance: KSuspendFunction1<ClockController, Unit>,
+ updateClockAppearance: suspend (ClockController, Resources) -> Unit,
+ clockPreviewConfig: ClockPreviewConfig,
) {
rootView.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
@@ -82,7 +82,10 @@ object KeyguardPreviewClockViewBinder {
.forEach { rootView.removeView(it) }
}
lastClock = currentClock
- updateClockAppearance(currentClock)
+ updateClockAppearance(
+ currentClock,
+ clockPreviewConfig.previewContext.resources,
+ )
if (viewModel.shouldHighlightSelectedAffordance) {
(currentClock.largeClock.layout.views +
@@ -98,7 +101,12 @@ object KeyguardPreviewClockViewBinder {
(it.parent as? ViewGroup)?.removeView(it)
rootView.addView(it)
}
- applyPreviewConstraints(context, rootView, currentClock, viewModel)
+ applyPreviewConstraints(
+ clockPreviewConfig,
+ rootView,
+ currentClock,
+ viewModel,
+ )
}
}
.invokeOnCompletion {
@@ -121,14 +129,14 @@ object KeyguardPreviewClockViewBinder {
}
private fun applyPreviewConstraints(
- context: Context,
+ clockPreviewConfig: ClockPreviewConfig,
rootView: ConstraintLayout,
previewClock: ClockController,
viewModel: KeyguardPreviewClockViewModel,
) {
val cs = ConstraintSet().apply { clone(rootView) }
- previewClock.largeClock.layout.applyPreviewConstraints(context, cs)
- previewClock.smallClock.layout.applyPreviewConstraints(context, cs)
+ previewClock.largeClock.layout.applyPreviewConstraints(clockPreviewConfig, cs)
+ previewClock.smallClock.layout.applyPreviewConstraints(clockPreviewConfig, cs)
// When selectedClockSize is the initial value, make both clocks invisible to avoid
// flickering
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
index baa681282a0b..e89be5d6ae4c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
@@ -17,7 +17,6 @@
package com.android.systemui.keyguard.ui.binder
-import android.content.Context
import android.view.View
import androidx.core.view.isInvisible
import androidx.lifecycle.Lifecycle
@@ -26,16 +25,16 @@ import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.keyguard.shared.model.ClockSizeSetting
import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewSmartspaceViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.plugins.clocks.ClockPreviewConfig
/** Binder for the small clock view, large clock view and smartspace. */
object KeyguardPreviewSmartspaceViewBinder {
@JvmStatic
fun bind(
- previewContext: Context,
smartspace: View,
- splitShadePreview: Boolean,
viewModel: KeyguardPreviewSmartspaceViewModel,
+ clockPreviewConfig: ClockPreviewConfig,
) {
smartspace.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
@@ -44,15 +43,9 @@ object KeyguardPreviewSmartspaceViewBinder {
val topPadding =
when (it) {
ClockSizeSetting.DYNAMIC ->
- viewModel.getLargeClockSmartspaceTopPadding(
- splitShadePreview,
- previewContext,
- )
+ viewModel.getLargeClockSmartspaceTopPadding(clockPreviewConfig)
ClockSizeSetting.SMALL ->
- viewModel.getSmallClockSmartspaceTopPadding(
- splitShadePreview,
- previewContext,
- )
+ viewModel.getSmallClockSmartspaceTopPadding(clockPreviewConfig)
}
smartspace.setTopPadding(topPadding)
}
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 ab9cffc05667..9924a3bcdd6a 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
@@ -22,6 +22,7 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
+import android.content.res.Resources
import android.graphics.Rect
import android.hardware.display.DisplayManager
import android.os.Bundle
@@ -47,6 +48,7 @@ import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.START
import androidx.constraintlayout.widget.ConstraintSet.TOP
import androidx.core.view.isInvisible
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.internal.policy.SystemBarUtils
import com.android.keyguard.ClockEventController
import com.android.keyguard.KeyguardClockSwitch
@@ -57,6 +59,7 @@ import com.android.systemui.common.ui.ConfigurationState
import com.android.systemui.communal.ui.binder.CommunalTutorialIndicatorViewBinder
import com.android.systemui.communal.ui.viewmodel.CommunalTutorialIndicatorViewModel
import com.android.systemui.coroutines.newTracingContext
+import com.android.systemui.customization.R as customR
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -80,9 +83,11 @@ import com.android.systemui.keyguard.ui.viewmodel.OccludingAppDeviceEntryMessage
import com.android.systemui.monet.ColorScheme
import com.android.systemui.monet.Style
import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.plugins.clocks.ClockPreviewConfig
import com.android.systemui.plugins.clocks.ThemeConfig
import com.android.systemui.plugins.clocks.WeatherData
import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shared.clocks.ClockRegistry
import com.android.systemui.shared.clocks.DefaultClockController
@@ -105,7 +110,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.flowOf
-import com.android.app.tracing.coroutines.launchTraced as launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.json.JSONException
@@ -352,8 +356,11 @@ constructor(
val topPadding: Int =
smartspaceViewModel.getLargeClockSmartspaceTopPadding(
- previewInSplitShade(),
- previewContext,
+ ClockPreviewConfig(
+ previewContext,
+ getPreviewShadeLayoutWide(display!!),
+ SceneContainerFlag.isEnabled,
+ )
)
val startPadding: Int = smartspaceViewModel.getSmartspaceStartPadding(previewContext)
val endPadding: Int = smartspaceViewModel.getSmartspaceEndPadding(previewContext)
@@ -436,11 +443,15 @@ constructor(
setUpClock(previewContext, rootView)
if (MigrateClocksToBlueprint.isEnabled) {
KeyguardPreviewClockViewBinder.bind(
- previewContext,
keyguardRootView,
clockViewModel,
clockRegistry,
::updateClockAppearance,
+ ClockPreviewConfig(
+ previewContext,
+ getPreviewShadeLayoutWide(display!!),
+ SceneContainerFlag.isEnabled,
+ ),
)
} else {
KeyguardPreviewClockViewBinder.bind(
@@ -455,10 +466,14 @@ constructor(
smartSpaceView?.let {
KeyguardPreviewSmartspaceViewBinder.bind(
- previewContext,
it,
- previewInSplitShade(),
smartspaceViewModel,
+ clockPreviewConfig =
+ ClockPreviewConfig(
+ previewContext,
+ getPreviewShadeLayoutWide(display!!),
+ SceneContainerFlag.isEnabled,
+ ),
)
}
setupCommunalTutorialIndicator(keyguardRootView)
@@ -552,20 +567,14 @@ constructor(
val layoutParams =
FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
- resources.getDimensionPixelSize(
- com.android.systemui.customization.R.dimen.small_clock_height
- ),
+ resources.getDimensionPixelSize(customR.dimen.small_clock_height),
)
layoutParams.topMargin =
SystemBarUtils.getStatusBarHeight(previewContext) +
- resources.getDimensionPixelSize(
- com.android.systemui.customization.R.dimen.small_clock_padding_top
- )
+ resources.getDimensionPixelSize(customR.dimen.small_clock_padding_top)
smallClockHostView.layoutParams = layoutParams
smallClockHostView.setPaddingRelative(
- /* start = */ resources.getDimensionPixelSize(
- com.android.systemui.customization.R.dimen.clock_padding_start
- ),
+ /* start = */ resources.getDimensionPixelSize(customR.dimen.clock_padding_start),
/* top = */ 0,
/* end = */ 0,
/* bottom = */ 0,
@@ -637,7 +646,7 @@ constructor(
onClockChanged()
}
- private suspend fun updateClockAppearance(clock: ClockController) {
+ private suspend fun updateClockAppearance(clock: ClockController, resources: Resources) {
if (!MigrateClocksToBlueprint.isEnabled) {
clockController.clock = clock
}
@@ -667,6 +676,11 @@ constructor(
if (MigrateClocksToBlueprint.isEnabled) {
clockController.clock = clock
}
+ // When set clock to clockController,it will reset fontsize based on context.resources
+ // We need to override it with overlaid resources
+ clock.largeClock.events.onFontSettingChanged(
+ resources.getDimensionPixelSize(customR.dimen.large_clock_text_size).toFloat()
+ )
}
private fun onClockChanged() {
@@ -676,7 +690,7 @@ constructor(
coroutineScope.launch {
val clock = clockRegistry.createCurrentClock()
clockController.clock = clock
- updateClockAppearance(clock)
+ updateClockAppearance(clock, context.resources)
updateLargeClock(clock)
updateSmallClock(clock)
}
@@ -742,12 +756,14 @@ constructor(
smallClockHostView.addView(clock.smallClock.view)
}
- /*
- * When multi_crop_preview_ui_flag is on, we can preview portrait in split shadow direction
- * or vice versa. So we need to decide preview direction by width and height
- */
- private fun previewInSplitShade(): Boolean {
- return width > height
+ private fun getPreviewShadeLayoutWide(display: Display): Boolean {
+ return if (display.displayId == 0) {
+ shadeInteractor.isShadeLayoutWide.value
+ } else {
+ // For the unfolded preview in a folded screen; it's landscape by default
+ // For the folded preview in an unfolded screen; it's portrait by default
+ display.name == "Inner Display"
+ }
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt
index 8622ffc04601..160380bb09bc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodBurnInSection.kt
@@ -19,6 +19,7 @@ package com.android.systemui.keyguard.ui.view.layout.sections
import android.content.Context
import android.view.View
+import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
@@ -47,11 +48,15 @@ constructor(
visibility = View.GONE
}
}
+
override fun addViews(constraintLayout: ConstraintLayout) {
if (!MigrateClocksToBlueprint.isEnabled) {
return
}
-
+ if (emptyView.parent != null) {
+ // As emptyView is lazy, it might be already attached.
+ (emptyView.parent as? ViewGroup)?.removeView(emptyView)
+ }
constraintLayout.addView(emptyView)
burnInLayer =
AodBurnInLayer(context).apply {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
index 6c98d5b01e4e..70bf8bca55b9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
@@ -235,9 +235,7 @@ constructor(
val smallClockBottom =
keyguardClockViewModel.getSmallClockTopMargin() +
- context.resources.getDimensionPixelSize(
- com.android.systemui.customization.R.dimen.small_clock_height
- )
+ context.resources.getDimensionPixelSize(customR.dimen.small_clock_height)
val dateWeatherSmartspaceHeight = getDimen(context, DATE_WEATHER_VIEW_HEIGHT).toFloat()
val marginBetweenSmartspaceAndNotification =
context.resources.getDimensionPixelSize(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index 3a7a640be85f..6e30e482bda0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
+import android.content.Context
import android.content.res.Resources
import androidx.annotation.VisibleForTesting
import androidx.constraintlayout.helper.widget.Layer
@@ -27,7 +28,8 @@ import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.shared.model.ClockSize
import com.android.systemui.keyguard.shared.model.ClockSizeSetting
-import com.android.systemui.res.R
+import com.android.systemui.plugins.clocks.ClockPreviewConfig
+import com.android.systemui.plugins.clocks.DefaultClockFaceLayout.Companion.getSmallClockTopPadding
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -46,6 +48,7 @@ import kotlinx.coroutines.flow.stateIn
class KeyguardClockViewModel
@Inject
constructor(
+ val context: Context,
keyguardClockInteractor: KeyguardClockInteractor,
@Application private val applicationScope: CoroutineScope,
aodNotificationIconViewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
@@ -158,16 +161,15 @@ constructor(
)
/** Calculates the top margin for the small clock. */
- fun getSmallClockTopMargin(): Int {
- val statusBarHeight = systemBarUtils.getStatusBarHeaderHeightKeyguard()
- return if (shadeInteractor.isShadeLayoutWide.value) {
- resources.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin) -
- if (SceneContainerFlag.isEnabled) statusBarHeight else 0
- } else {
- resources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) +
- if (!SceneContainerFlag.isEnabled) statusBarHeight else 0
- }
- }
+ fun getSmallClockTopMargin(): Int =
+ getSmallClockTopPadding(
+ ClockPreviewConfig(
+ context,
+ shadeInteractor.isShadeLayoutWide.value,
+ SceneContainerFlag.isEnabled,
+ ),
+ systemBarUtils.getStatusBarHeaderHeightKeyguard(),
+ )
val smallClockTopMargin =
combine(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
index 65c0f57b76f5..1c4498212502 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
@@ -17,11 +17,12 @@
package com.android.systemui.keyguard.ui.viewmodel
import android.content.Context
-import com.android.internal.policy.SystemBarUtils
import com.android.systemui.customization.R as customR
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
import com.android.systemui.keyguard.shared.model.ClockSizeSetting
-import com.android.systemui.res.R
+import com.android.systemui.plugins.clocks.ClockPreviewConfig
+import com.android.systemui.plugins.clocks.DefaultClockFaceLayout.Companion.getSmallClockTopPadding
+import com.android.systemui.statusbar.ui.SystemBarUtilsProxy
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
@@ -35,6 +36,7 @@ constructor(
interactor: KeyguardClockInteractor,
val smartspaceViewModel: KeyguardSmartspaceViewModel,
val clockViewModel: KeyguardClockViewModel,
+ private val systemBarUtils: SystemBarUtilsProxy,
) {
val selectedClockSize: StateFlow<ClockSizeSetting> = interactor.selectedClockSize
@@ -59,29 +61,18 @@ constructor(
return KeyguardSmartspaceViewModel.getSmartspaceEndMargin(context)
}
- fun getSmallClockSmartspaceTopPadding(splitShadePreview: Boolean, context: Context): Int {
- return getSmallClockTopPadding(splitShadePreview, context) +
- context.resources.getDimensionPixelSize(
- com.android.systemui.customization.R.dimen.small_clock_height
- )
- }
-
- fun getLargeClockSmartspaceTopPadding(splitShadePreview: Boolean, context: Context): Int {
- return getSmallClockTopPadding(splitShadePreview, context)
- }
-
/*
* SmallClockTopPadding decides the top position of smartspace
*/
- private fun getSmallClockTopPadding(splitShadePreview: Boolean, context: Context): Int {
- return with(context.resources) {
- if (splitShadePreview) {
- getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin)
- } else {
- getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) +
- SystemBarUtils.getStatusBarHeight(context) +
- getDimensionPixelSize(customR.dimen.keyguard_smartspace_top_offset)
- }
- }
+ fun getSmallClockSmartspaceTopPadding(config: ClockPreviewConfig): Int {
+ return getSmallClockTopPadding(config, systemBarUtils.getStatusBarHeaderHeightKeyguard()) +
+ config.previewContext.resources.getDimensionPixelSize(customR.dimen.small_clock_height)
+ }
+
+ fun getLargeClockSmartspaceTopPadding(clockPreviewConfig: ClockPreviewConfig): Int {
+ return getSmallClockTopPadding(
+ clockPreviewConfig,
+ systemBarUtils.getStatusBarHeaderHeightKeyguard(),
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
index 6f29004d4f3f..618b04700afb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModel.kt
@@ -23,6 +23,7 @@ import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.scene.ui.viewmodel.UserActionsViewModel
import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -44,6 +45,7 @@ constructor(
private val deviceEntryInteractor: DeviceEntryInteractor,
private val communalInteractor: CommunalInteractor,
private val shadeInteractor: ShadeInteractor,
+ private val occlusionInteractor: SceneContainerOcclusionInteractor,
) : UserActionsViewModel() {
override suspend fun hydrateActions(setActions: (Map<UserAction, UserActionResult>) -> Unit) {
@@ -57,7 +59,8 @@ constructor(
deviceEntryInteractor.isUnlocked,
communalInteractor.isCommunalAvailable,
shadeInteractor.shadeMode,
- ) { isDeviceUnlocked, isCommunalAvailable, shadeMode ->
+ occlusionInteractor.isOccludingActivityShown,
+ ) { isDeviceUnlocked, isCommunalAvailable, shadeMode, isOccluded ->
buildList {
if (isCommunalAvailable) {
add(Swipe.Start to Scenes.Communal)
@@ -67,7 +70,8 @@ constructor(
addAll(
when (shadeMode) {
- ShadeMode.Single -> singleShadeActions()
+ ShadeMode.Single ->
+ singleShadeActions(isDownFromTopEdgeEnabled = !isOccluded)
ShadeMode.Split -> splitShadeActions()
ShadeMode.Dual -> dualShadeActions()
}
diff --git a/packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt
index 881228d597b0..93ecae32ac17 100644
--- a/packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt
+++ b/packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt
@@ -21,11 +21,11 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.snapshots.StateFactoryMarker
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.app.tracing.coroutines.traceCoroutine
+import com.android.systemui.log.table.TableLogBuffer
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
-import com.android.app.tracing.coroutines.launchTraced as launch
/**
* Keeps snapshot/Compose [State]s up-to-date.
@@ -47,6 +47,12 @@ class Hydrator(
* concatenation or templating.
*/
private val traceName: String,
+ /**
+ * An optional [TableLogBuffer] to log emissions to the states. [traceName] will be used as the
+ * prefix for the columns logged by this [Hydrator], allowing to aggregate multiple hydrators in
+ * the same table.
+ */
+ private val tableLogBuffer: TableLogBuffer? = null,
) : ExclusiveActivatable() {
private val children = mutableListOf<NamedActivatable>()
@@ -62,15 +68,8 @@ class Hydrator(
* automatically set on the returned [State].
*/
@StateFactoryMarker
- fun <T> hydratedStateOf(
- traceName: String,
- source: StateFlow<T>,
- ): State<T> {
- return hydratedStateOf(
- traceName = traceName,
- initialValue = source.value,
- source = source,
- )
+ fun <T> hydratedStateOf(traceName: String, source: StateFlow<T>): State<T> {
+ return hydratedStateOf(traceName = traceName, initialValue = source.value, source = source)
}
/**
@@ -81,26 +80,44 @@ class Hydrator(
* performance findings with actual code. One recommendation: prefer whole string literals
* instead of some complex concatenation or templating scheme. Use `null` to disable
* performance tracing for this state.
+ *
+ * If a [TableLogBuffer] was provided, every emission to the flow will be logged using the
+ * [traceName] as the column name. For this to work correctly, all the states in the same
+ * hydrator should have different [traceName]. Use `null` to disable logging for this state.
+ *
* @param initialValue The first value to place on the [State]
* @param source The upstream [Flow] to collect from; values emitted to it will be automatically
* set on the returned [State].
*/
@StateFactoryMarker
- fun <T> hydratedStateOf(
- traceName: String?,
- initialValue: T,
- source: Flow<T>,
- ): State<T> {
+ fun <T> hydratedStateOf(traceName: String?, initialValue: T, source: Flow<T>): State<T> {
check(!isActive) { "Cannot call hydratedStateOf after Hydrator is already active." }
val mutableState = mutableStateOf(initialValue)
+ traceName?.let { name ->
+ tableLogBuffer?.logChange(
+ prefix = this.traceName,
+ columnName = name,
+ value = initialValue?.toString(),
+ isInitial = true,
+ )
+ }
children.add(
NamedActivatable(
traceName = traceName,
activatable =
object : ExclusiveActivatable() {
override suspend fun onActivated(): Nothing {
- source.collect { mutableState.value = it }
+ source.collect {
+ traceName?.let { name ->
+ tableLogBuffer?.logChange(
+ prefix = this@Hydrator.traceName,
+ columnName = name,
+ value = it?.toString(),
+ )
+ }
+ mutableState.value = it
+ }
awaitCancellation()
}
},
@@ -122,8 +139,5 @@ class Hydrator(
}
}
- private data class NamedActivatable(
- val traceName: String?,
- val activatable: Activatable,
- )
+ private data class NamedActivatable(val traceName: String?, val activatable: Activatable)
}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
index 35efd751b8fe..7d3094827e17 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionManagerRepository.kt
@@ -20,6 +20,7 @@ import android.app.ActivityManager.RunningTaskInfo
import android.hardware.display.DisplayManager
import android.media.projection.MediaProjectionInfo
import android.media.projection.MediaProjectionManager
+import android.media.projection.StopReason
import android.os.Handler
import android.view.ContentRecordingSession
import android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY
@@ -72,7 +73,7 @@ constructor(
}
}
- override suspend fun stopProjecting() {
+ override suspend fun stopProjecting(@StopReason stopReason: Int) {
withContext(backgroundDispatcher) {
logger.log(
TAG,
@@ -80,7 +81,7 @@ constructor(
{},
{ "Requesting MediaProjectionManager#stopActiveProjection" },
)
- mediaProjectionManager.stopActiveProjection()
+ mediaProjectionManager.stopActiveProjection(stopReason)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt
index 50182d7a3b33..a01d8c2c98de 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/data/repository/MediaProjectionRepository.kt
@@ -17,6 +17,7 @@
package com.android.systemui.mediaprojection.data.repository
import android.app.ActivityManager.RunningTaskInfo
+import android.media.projection.StopReason
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import kotlinx.coroutines.flow.Flow
@@ -27,7 +28,7 @@ interface MediaProjectionRepository {
suspend fun switchProjectedTask(task: RunningTaskInfo)
/** Stops the currently active projection. */
- suspend fun stopProjecting()
+ suspend fun stopProjecting(@StopReason stopReason: Int)
/** Represents the current [MediaProjectionState]. */
val mediaProjectionState: Flow<MediaProjectionState>
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 80ac2fcd4aa4..0a4e8c660761 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -18,6 +18,7 @@ package com.android.systemui.navigationbar.gestural;
import static android.content.pm.ActivityInfo.CONFIG_FONT_SCALE;
import static android.view.InputDevice.SOURCE_MOUSE;
import static android.view.InputDevice.SOURCE_TOUCHPAD;
+import static android.view.MotionEvent.TOOL_TYPE_FINGER;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
import static com.android.systemui.Flags.edgebackGestureHandlerGetRunningTasksBackground;
@@ -216,6 +217,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
private final int mDisplayId;
private final UiThreadContext mUiThreadContext;
+ private final Handler mBgHandler;
private final Executor mBackgroundExecutor;
private final Rect mPipExcludedBounds = new Rect();
@@ -378,11 +380,14 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
@Override
public void onInputDeviceAdded(int deviceId) {
if (isTrackpadDevice(deviceId)) {
- boolean wasEmpty = mTrackpadsConnected.isEmpty();
- mTrackpadsConnected.add(deviceId);
- if (wasEmpty) {
- update();
- }
+ // This updates the gesture handler state and should be running on the main thread.
+ mUiThreadContext.getHandler().post(() -> {
+ boolean wasEmpty = mTrackpadsConnected.isEmpty();
+ mTrackpadsConnected.add(deviceId);
+ if (wasEmpty) {
+ update();
+ }
+ });
}
}
@@ -391,10 +396,13 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
@Override
public void onInputDeviceRemoved(int deviceId) {
- mTrackpadsConnected.remove(deviceId);
- if (mTrackpadsConnected.isEmpty()) {
- update();
- }
+ // This updates the gesture handler state and should be running on the main thread.
+ mUiThreadContext.getHandler().post(() -> {
+ mTrackpadsConnected.remove(deviceId);
+ if (mTrackpadsConnected.isEmpty()) {
+ update();
+ }
+ });
}
private void update() {
@@ -408,12 +416,12 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
}
private boolean isTrackpadDevice(int deviceId) {
+ // This is a blocking binder call that should run on a bg thread.
InputDevice inputDevice = mInputManager.getInputDevice(deviceId);
if (inputDevice == null) {
return false;
}
- return inputDevice.getSources() == (InputDevice.SOURCE_MOUSE
- | InputDevice.SOURCE_TOUCHPAD);
+ return inputDevice.getSources() == (SOURCE_MOUSE | SOURCE_TOUCHPAD);
}
};
@@ -457,6 +465,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mDisplayId = context.getDisplayId();
mUiThreadContext = uiThreadContext;
mBackgroundExecutor = backgroundExecutor;
+ mBgHandler = bgHandler;
mUserTracker = userTracker;
mOverviewProxyService = overviewProxyService;
mSysUiState = sysUiState;
@@ -611,9 +620,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
mIsAttached = true;
mOverviewProxyService.addCallback(mQuickSwitchListener);
mSysUiState.addCallback(mSysUiStateCallback);
- mInputManager.registerInputDeviceListener(
- mInputDeviceListener,
- mUiThreadContext.getHandler());
+ mInputManager.registerInputDeviceListener(mInputDeviceListener, mBgHandler);
int[] inputDevices = mInputManager.getInputDeviceIds();
for (int inputDeviceId : inputDevices) {
mInputDeviceListener.onInputDeviceAdded(inputDeviceId);
@@ -1089,8 +1096,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
&& isValidTrackpadBackGesture(true /* isTrackpadEvent */);
} else {
mAllowGesture = isBackAllowedCommon && !mUsingThreeButtonNav && isWithinInsets
- && isWithinTouchRegion((int) ev.getX(), (int) ev.getY())
- && !isButtonPressFromTrackpad(ev);
+ && isWithinTouchRegion((int) ev.getX(), (int) ev.getY())
+ && !isButtonPressFromTrackpad(ev);
}
if (mAllowGesture) {
mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
@@ -1202,10 +1209,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
}
private boolean isButtonPressFromTrackpad(MotionEvent ev) {
- // We don't allow back for button press from the trackpad, and yet we do with a mouse.
- int sources = InputManager.getInstance().getInputDevice(ev.getDeviceId()).getSources();
- int sourceTrackpad = (SOURCE_MOUSE | SOURCE_TOUCHPAD);
- return (sources & sourceTrackpad) == sourceTrackpad && ev.getButtonState() != 0;
+ return ev.getSource() == (SOURCE_MOUSE | SOURCE_TOUCHPAD)
+ && ev.getToolType(ev.getActionIndex()) == TOOL_TYPE_FINGER;
}
private void dispatchToBackAnimation(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
index d715f42ed499..dc188c24e02b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
@@ -16,8 +16,11 @@
package com.android.systemui.qs;
+import static com.android.systemui.Flags.gsfQuickSettings;
+
import android.content.ClipData;
import android.content.ClipboardManager;
+import android.graphics.Typeface;
import android.text.TextUtils;
import android.view.View;
import android.widget.TextView;
@@ -64,6 +67,9 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme
mRetailModeInteractor = retailModeInteractor;
mBuildText = mView.findViewById(R.id.build);
+ if (gsfQuickSettings()) {
+ mBuildText.setTypeface(Typeface.create("gsf-body-medium", Typeface.NORMAL));
+ }
mPageIndicator = mView.findViewById(R.id.footer_page_indicator);
mEditButton = mView.findViewById(android.R.id.edit);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index 21c45c550e08..5167d173647e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -233,6 +233,7 @@ constructor(
// Only allow scrolling when we are fully expanded. That way, we don't intercept
// swipes in lockscreen (when somehow QS is receiving touches).
{ (scrollState.canScrollForward && viewModel.isQsFullyExpanded) || isCustomizing },
+ viewModel::emitMotionEventForFalsingSwipeNested,
)
frame.addView(
composeView,
@@ -718,7 +719,6 @@ constructor(
max =
QuickSettingsShade.Dimensions.GridMaxHeight
),
- containerViewModel.editModeViewModel::startEditing,
)
}
}
@@ -951,6 +951,7 @@ private class FrameLayoutTouchPassthrough(
private val clippingEnabledProvider: () -> Boolean,
private val clippingTopProvider: () -> Int,
private val canScrollForwardQs: () -> Boolean,
+ private val emitMotionEventForFalsing: () -> Unit,
) : FrameLayout(context) {
override fun isTransformedTouchPointInView(
x: Float,
@@ -967,6 +968,32 @@ private class FrameLayoutTouchPassthrough(
val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
var downY = 0f
+ var preventingIntercept = false
+
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+ val action = event.actionMasked
+ when (action) {
+ MotionEvent.ACTION_DOWN -> {
+ preventingIntercept = false
+ if (canScrollVertically(1)) {
+ // If we can scroll down, make sure we're not intercepted by the parent
+ preventingIntercept = true
+ parent?.requestDisallowInterceptTouchEvent(true)
+ } else if (!canScrollVertically(-1)) {
+ // Don't pass on the touch to the view, because scrolling will unconditionally
+ // disallow interception even if we can't scroll.
+ // if a user can't scroll at all, we should never listen to the touch.
+ return false
+ }
+ }
+ MotionEvent.ACTION_UP -> {
+ if (preventingIntercept) {
+ emitMotionEventForFalsing()
+ }
+ }
+ }
+ return super.onTouchEvent(event)
+ }
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
// If there's a touch on this view and we can scroll down, we don't want to be intercepted
@@ -974,8 +1001,10 @@ private class FrameLayoutTouchPassthrough(
when (action) {
MotionEvent.ACTION_DOWN -> {
+ preventingIntercept = false
// If we can scroll down, make sure none of our parents intercepts us.
if (canScrollForwardQs()) {
+ preventingIntercept = true
parent?.requestDisallowInterceptTouchEvent(true)
}
downY = ev.y
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeLog.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeLog.kt
new file mode 100644
index 000000000000..5f151eba5c84
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeLog.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.qs.composefragment.dagger
+
+import javax.inject.Qualifier
+
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class QSFragmentComposeLog
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
index 2ec729223a8d..4c9df116bd97 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/dagger/QSFragmentComposeModule.kt
@@ -18,7 +18,8 @@ package com.android.systemui.qs.composefragment.dagger
import android.content.Context
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.TableLogBufferFactory
import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.util.Utils
@@ -38,5 +39,14 @@ interface QSFragmentComposeModule {
fun providesUsingMedia(@ShadeDisplayAware context: Context): Boolean {
return QSComposeFragment.isEnabled && Utils.useQsMediaPlayer(context)
}
+
+ @Provides
+ @SysUISingleton
+ @QSFragmentComposeLog
+ fun providesQSFragmentComposeViewModelTableLog(
+ factory: TableLogBufferFactory
+ ): TableLogBuffer {
+ return factory.create("QSFragmentComposeViewModel", 200)
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
index e3de6d5152e4..02498d69b83d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
@@ -31,6 +31,8 @@ import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.keyguard.BouncerPanelExpansionCalculator
import com.android.systemui.Dumpable
import com.android.systemui.animation.ShadeInterpolation
+import com.android.systemui.classifier.Classifier
+import com.android.systemui.classifier.domain.interactor.FalsingInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
@@ -39,6 +41,7 @@ import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QQS
import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager.Companion.LOCATION_QS
@@ -48,6 +51,7 @@ import com.android.systemui.media.dagger.MediaModule.QS_PANEL
import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.FooterActionsController
+import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeLog
import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.panels.domain.interactor.TileSquishinessInteractor
@@ -100,7 +104,9 @@ constructor(
@ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
private val largeScreenHeaderHelper: LargeScreenHeaderHelper,
private val squishinessInteractor: TileSquishinessInteractor,
+ private val falsingInteractor: FalsingInteractor,
private val inFirstPageViewModel: InFirstPageViewModel,
+ @QSFragmentComposeLog private val tableLogBuffer: TableLogBuffer,
mediaInRowInLandscapeViewModelFactory: MediaInRowInLandscapeViewModel.Factory,
@Named(QUICK_QS_PANEL) val qqsMediaHost: MediaHost,
@Named(QS_PANEL) val qsMediaHost: MediaHost,
@@ -112,7 +118,7 @@ constructor(
private val qqsMediaInRowViewModel = mediaInRowInLandscapeViewModelFactory.create(LOCATION_QQS)
private val qsMediaInRowViewModel = mediaInRowInLandscapeViewModelFactory.create(LOCATION_QS)
- private val hydrator = Hydrator("QSFragmentComposeViewModel.hydrator")
+ private val hydrator = Hydrator("QSFragmentComposeViewModel.hydrator", tableLogBuffer)
val footerActionsViewModel =
footerActionsViewModelFactory.create(lifecycleScope).also {
@@ -434,6 +440,10 @@ constructor(
}
}
+ fun emitMotionEventForFalsingSwipeNested() {
+ falsingInteractor.isFalseTouch(Classifier.QS_SWIPE_NESTED)
+ }
+
override suspend fun onActivated(): Nothing {
initMediaHosts() // init regardless of using media (same as current QS).
coroutineScope {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index f8d408054d25..0e64820c984e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -15,6 +15,8 @@
*/
package com.android.systemui.qs.customize;
+import static com.android.systemui.Flags.gsfQuickSettings;
+
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
@@ -81,6 +83,10 @@ public class QSCustomizer extends LinearLayout {
mToolbar.getMenu().add(Menu.NONE, MENU_RESET, 0, com.android.internal.R.string.reset)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
mToolbar.setTitle(R.string.qs_edit);
+ if (gsfQuickSettings()) {
+ mToolbar.setTitleTextAppearance(context, R.style.TextAppearance_QSEditTitle);
+ }
+
mRecyclerView = findViewById(android.R.id.list);
mTransparentView = findViewById(R.id.customizer_transparent_view);
DefaultItemAnimator animator = new DefaultItemAnimator();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 829c419fc07f..db778a208b1e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -14,12 +14,15 @@
package com.android.systemui.qs.customize;
+import static com.android.systemui.Flags.gsfQuickSettings;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
+import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.view.LayoutInflater;
@@ -309,6 +312,10 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
if (viewType == TYPE_HEADER) {
View v = inflater.inflate(R.layout.qs_customize_header, parent, false);
v.setMinimumHeight(calculateHeaderMinHeight(context));
+ if (gsfQuickSettings()) {
+ ((TextView) v.findViewById(android.R.id.title)).setTypeface(
+ Typeface.create("gsf-label-large", Typeface.NORMAL));
+ }
return new Holder(v);
}
if (viewType == TYPE_DIVIDER) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditModeButton.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditModeButton.kt
new file mode 100644
index 000000000000..c2764f9f338b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditModeButton.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.panels.ui.compose
+
+import androidx.compose.foundation.shape.CornerSize
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Edit
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.android.systemui.lifecycle.rememberViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.EditModeButtonViewModel
+import com.android.systemui.qs.ui.compose.borderOnFocus
+import com.android.systemui.res.R
+
+@Composable
+fun EditModeButton(
+ viewModelFactory: EditModeButtonViewModel.Factory,
+ modifier: Modifier = Modifier,
+) {
+ val viewModel = rememberViewModel(traceName = "EditModeButton") { viewModelFactory.create() }
+ CompositionLocalProvider(
+ value = LocalContentColor provides MaterialTheme.colorScheme.onSurface
+ ) {
+ IconButton(
+ onClick = viewModel::onButtonClick,
+ shape = RoundedCornerShape(CornerSize(28.dp)),
+ modifier =
+ modifier.borderOnFocus(
+ color = MaterialTheme.colorScheme.secondary,
+ cornerSize = CornerSize(24.dp),
+ ),
+ ) {
+ Icon(
+ imageVector = Icons.Default.Edit,
+ contentDescription = stringResource(id = R.string.qs_edit),
+ )
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
index c729c7c15176..14abfa2313d8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
@@ -68,29 +68,16 @@ class EditTileListState(
return _tiles.indexOfFirst { it is TileGridCell && it.tile.tileSpec == tileSpec }
}
- /**
- * Whether the tile with this [TileSpec] is currently an icon in the [EditTileListState]
- *
- * @return true if the tile is an icon, false if it's large, null if the tile isn't in the list
- */
- fun isIcon(tileSpec: TileSpec): Boolean? {
- val index = indexOf(tileSpec)
- return if (index != -1) {
- val cell = _tiles[index]
- cell as TileGridCell
- return cell.isIcon
- } else {
- null
- }
- }
-
- /** Toggle the size of the tile corresponding to the [TileSpec] */
- fun toggleSize(tileSpec: TileSpec) {
+ /** Resize the tile corresponding to the [TileSpec] to [toIcon] */
+ fun resizeTile(tileSpec: TileSpec, toIcon: Boolean) {
val fromIndex = indexOf(tileSpec)
if (fromIndex != -1) {
- val cell = _tiles.removeAt(fromIndex)
- cell as TileGridCell
- _tiles.add(fromIndex, cell.copy(width = if (cell.isIcon) largeTilesSpan else 1))
+ val cell = _tiles[fromIndex] as TileGridCell
+
+ if (cell.isIcon == toIcon) return
+
+ _tiles.removeAt(fromIndex)
+ _tiles.add(fromIndex, cell.copy(width = if (toIcon) 1 else largeTilesSpan))
regenerateGrid(fromIndex)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
index 0d375817b705..a22eb3a8d517 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
@@ -27,12 +27,7 @@ import com.android.systemui.qs.pipeline.shared.TileSpec
/** A layout of tiles, indicating how they should be composed when showing in QS or in edit mode. */
interface GridLayout {
- @Composable
- fun SceneScope.TileGrid(
- tiles: List<TileViewModel>,
- modifier: Modifier,
- editModeStart: () -> Unit,
- )
+ @Composable fun SceneScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier)
@Composable
fun EditTileGrid(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
index 789fdebc36eb..b6dbf4db57a4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
@@ -16,6 +16,7 @@
package com.android.systemui.qs.panels.ui.compose
+import android.view.MotionEvent
import androidx.compose.foundation.layout.Arrangement.spacedBy
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
@@ -29,22 +30,15 @@ import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CornerSize
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Edit
-import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
-import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.SceneScope
import com.android.compose.modifiers.padding
@@ -55,10 +49,10 @@ import com.android.systemui.lifecycle.rememberViewModel
import com.android.systemui.qs.panels.dagger.PaginatedBaseLayoutType
import com.android.systemui.qs.panels.ui.compose.Dimensions.FooterHeight
import com.android.systemui.qs.panels.ui.compose.Dimensions.InterPageSpacing
+import com.android.systemui.qs.panels.ui.viewmodel.EditModeButtonViewModel
import com.android.systemui.qs.panels.ui.viewmodel.PaginatedGridViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
import com.android.systemui.qs.ui.compose.borderOnFocus
-import com.android.systemui.res.R
import javax.inject.Inject
class PaginatedGridLayout
@@ -68,11 +62,7 @@ constructor(
@PaginatedBaseLayoutType private val delegateGridLayout: PaginatableGridLayout,
) : GridLayout by delegateGridLayout {
@Composable
- override fun SceneScope.TileGrid(
- tiles: List<TileViewModel>,
- modifier: Modifier,
- editModeStart: () -> Unit,
- ) {
+ override fun SceneScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) {
val viewModel =
rememberViewModel(traceName = "PaginatedGridLayout-TileGrid") {
viewModelFactory.create()
@@ -115,7 +105,13 @@ constructor(
state = pagerState,
modifier =
Modifier.sysuiResTag("qs_pager")
- .padding(horizontal = { -contentPaddingValue.roundToPx() }),
+ .padding(horizontal = { -contentPaddingValue.roundToPx() })
+ .pointerInteropFilter { event ->
+ if (event.actionMasked == MotionEvent.ACTION_UP) {
+ viewModel.registerSideSwipeGesture()
+ }
+ false
+ },
contentPadding = contentPadding,
pageSpacing = if (pages.size > 1) InterPageSpacing else 0.dp,
beyondViewportPageCount = 1,
@@ -123,14 +119,12 @@ constructor(
) {
val page = pages[it]
- with(delegateGridLayout) {
- TileGrid(tiles = page, modifier = Modifier, editModeStart = {})
- }
+ with(delegateGridLayout) { TileGrid(tiles = page, modifier = Modifier) }
}
FooterBar(
buildNumberViewModelFactory = viewModel.buildNumberViewModelFactory,
pagerState = pagerState,
- editModeStart = editModeStart,
+ editButtonViewModelFactory = viewModel.editModeButtonViewModelFactory,
)
}
}
@@ -145,7 +139,7 @@ private object Dimensions {
private fun FooterBar(
buildNumberViewModelFactory: BuildNumberViewModel.Factory,
pagerState: PagerState,
- editModeStart: () -> Unit,
+ editButtonViewModelFactory: EditModeButtonViewModel.Factory,
) {
// Use requiredHeight so it won't be squished if the view doesn't quite fit. As this is
// expected to be inside a scrollable container, this should not be an issue.
@@ -181,24 +175,7 @@ private fun FooterBar(
)
Row(Modifier.weight(1f)) {
Spacer(modifier = Modifier.weight(1f))
- CompositionLocalProvider(
- value = LocalContentColor provides MaterialTheme.colorScheme.onSurface
- ) {
- IconButton(
- onClick = editModeStart,
- shape = RoundedCornerShape(CornerSize(28.dp)),
- modifier =
- Modifier.borderOnFocus(
- color = MaterialTheme.colorScheme.secondary,
- cornerSize = CornerSize(FooterHeight / 2),
- ),
- ) {
- Icon(
- imageVector = Icons.Default.Edit,
- contentDescription = stringResource(id = R.string.qs_edit),
- )
- }
- }
+ EditModeButton(viewModelFactory = editButtonViewModelFactory)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
index 1a5297b10e37..6c1906bb906f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
@@ -24,13 +24,9 @@ import com.android.compose.animation.scene.SceneScope
import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
@Composable
-fun SceneScope.TileGrid(
- viewModel: TileGridViewModel,
- modifier: Modifier = Modifier,
- editModeStart: () -> Unit,
-) {
+fun SceneScope.TileGrid(viewModel: TileGridViewModel, modifier: Modifier = Modifier) {
val gridLayout by viewModel.gridLayout.collectAsStateWithLifecycle()
val tiles by viewModel.tileViewModels.collectAsStateWithLifecycle(emptyList())
- with(gridLayout) { TileGrid(tiles, modifier, editModeStart) }
+ with(gridLayout) { TileGrid(tiles, modifier) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
index 31ea60e2f0bc..c6141a1a7cc2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
@@ -20,7 +20,6 @@ package com.android.systemui.qs.panels.ui.compose.infinitegrid
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.fadeIn
@@ -75,7 +74,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
-import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -124,8 +122,12 @@ import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults
import com.android.systemui.qs.panels.ui.compose.infinitegrid.EditModeTileDefaults.CurrentTilesGridPadding
import com.android.systemui.qs.panels.ui.compose.selection.MutableSelectionState
import com.android.systemui.qs.panels.ui.compose.selection.ResizableTileContainer
-import com.android.systemui.qs.panels.ui.compose.selection.TileWidths
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation.FinalResizeOperation
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation.TemporaryResizeOperation
import com.android.systemui.qs.panels.ui.compose.selection.clearSelectionTile
+import com.android.systemui.qs.panels.ui.compose.selection.rememberResizingState
import com.android.systemui.qs.panels.ui.compose.selection.rememberSelectionState
import com.android.systemui.qs.panels.ui.compose.selection.selectableTile
import com.android.systemui.qs.panels.ui.model.GridCell
@@ -136,10 +138,10 @@ import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.shared.model.groupAndSort
import com.android.systemui.res.R
+import kotlin.math.max
import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.collectLatest
object TileType
@@ -181,15 +183,7 @@ fun DefaultEditTileGrid(
onStopEditing: () -> Unit,
onReset: (() -> Unit)?,
) {
- val currentListState by rememberUpdatedState(listState)
- val selectionState =
- rememberSelectionState(
- onResize = { currentListState.toggleSize(it) },
- onResizeEnd = { spec ->
- // Commit the size currently in the list
- currentListState.isIcon(spec)?.let { onResize(spec, it) }
- },
- )
+ val selectionState = rememberSelectionState()
val reset: (() -> Unit)? =
if (onReset != null) {
{
@@ -349,10 +343,21 @@ private fun CurrentTilesGrid(
}
.testTag(CURRENT_TILES_GRID_TEST_TAG),
) {
- EditTiles(cells, columns, listState, selectionState, coroutineScope, largeTilesSpan) { spec
- ->
- // Toggle the current size of the tile
- currentListState.isIcon(spec)?.let { onResize(spec, !it) }
+ EditTiles(cells, columns, listState, selectionState, coroutineScope, largeTilesSpan) {
+ resizingOperation ->
+ when (resizingOperation) {
+ is TemporaryResizeOperation -> {
+ currentListState.resizeTile(resizingOperation.spec, resizingOperation.toIcon)
+ }
+ is FinalResizeOperation -> {
+ // Commit the new size of the tile
+ onResize(resizingOperation.spec, resizingOperation.toIcon)
+
+ // Mark the selection as automatic in case the tile ends up moving to a
+ // different row with its new size.
+ selectionState.select(resizingOperation.spec, manual = false)
+ }
+ }
}
}
}
@@ -373,7 +378,7 @@ private fun AvailableTileGrid(
// Available tiles
Column(
- verticalArrangement = spacedBy(CommonTileDefaults.TileArrangementPadding),
+ verticalArrangement = spacedBy(TileArrangementPadding),
horizontalAlignment = Alignment.Start,
modifier =
Modifier.fillMaxWidth().wrapContentHeight().testTag(AVAILABLE_TILES_GRID_TEST_TAG),
@@ -387,7 +392,7 @@ private fun AvailableTileGrid(
)
tiles.chunked(columns).forEach { row ->
Row(
- horizontalArrangement = spacedBy(CommonTileDefaults.TileArrangementPadding),
+ horizontalArrangement = spacedBy(TileArrangementPadding),
modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Max),
) {
row.forEachIndexed { index, tileGridCell ->
@@ -436,7 +441,7 @@ fun LazyGridScope.EditTiles(
selectionState: MutableSelectionState,
coroutineScope: CoroutineScope,
largeTilesSpan: Int,
- onToggleSize: (spec: TileSpec) -> Unit,
+ onResize: (operation: ResizeOperation) -> Unit,
) {
items(
count = cells.size,
@@ -464,7 +469,7 @@ fun LazyGridScope.EditTiles(
index = index,
dragAndDropState = dragAndDropState,
selectionState = selectionState,
- onToggleSize = onToggleSize,
+ onResize = onResize,
coroutineScope = coroutineScope,
bounceableInfo = cells.bounceableInfo(index, columns),
largeTilesSpan = largeTilesSpan,
@@ -482,7 +487,7 @@ private fun TileGridCell(
index: Int,
dragAndDropState: DragAndDropState,
selectionState: MutableSelectionState,
- onToggleSize: (spec: TileSpec) -> Unit,
+ onResize: (operation: ResizeOperation) -> Unit,
coroutineScope: CoroutineScope,
largeTilesSpan: Int,
bounceableInfo: BounceableInfo,
@@ -511,28 +516,47 @@ private fun TileGridCell(
selected = selectionState.selection?.tileSpec == cell.tile.tileSpec
}
- // Current base, min and max width of this tile
- var tileWidths: TileWidths? by remember { mutableStateOf(null) }
- val padding = with(LocalDensity.current) { TileArrangementPadding.roundToPx() }
+ val state = rememberResizingState(cell.tile.tileSpec, cell.isIcon)
+
+ val progress: () -> Float = {
+ if (selected) {
+ // If selected, return the manual progress from the drag
+ state.progress()
+ } else {
+ // Else, return the target progress for the tile format
+ if (cell.isIcon) 0f else 1f
+ }
+ }
+
+ if (!selected) {
+ // Update the draggable anchor state when the tile's size is not manually toggled
+ LaunchedEffect(cell.isIcon) { state.updateCurrentValue(cell.isIcon) }
+ } else {
+ // If the tile is selected, listen to new target values from the draggable anchor to toggle
+ // the tile's size
+ LaunchedEffect(state.temporaryResizeOperation) { onResize(state.temporaryResizeOperation) }
+ LaunchedEffect(state.finalResizeOperation) { onResize(state.finalResizeOperation) }
+ }
+
+ val totalPadding =
+ with(LocalDensity.current) { (largeTilesSpan - 1) * TileArrangementPadding.roundToPx() }
ResizableTileContainer(
selected = selected,
- selectionState = selectionState,
+ state = state,
selectionAlpha = { selectionAlpha },
selectionColor = selectionColor,
- tileWidths = { tileWidths },
modifier =
modifier
.height(TileHeight)
.fillMaxWidth()
.onSizeChanged {
// Grab the size before the bounceable to get the idle width
- val totalPadding = (largeTilesSpan - 1) * padding
val min =
if (cell.isIcon) it.width else (it.width - totalPadding) / largeTilesSpan
val max =
if (cell.isIcon) (it.width * largeTilesSpan) + totalPadding else it.width
- tileWidths = TileWidths(it.width, min, max)
+ state.updateAnchors(min.toFloat(), max.toFloat())
}
.bounceable(
bounceable = currentBounceableInfo.bounceable,
@@ -552,7 +576,7 @@ private fun TileGridCell(
listOf(
// TODO(b/367748260): Add final accessibility actions
CustomAccessibilityAction("Toggle size") {
- onToggleSize(cell.tile.tileSpec)
+ onResize(FinalResizeOperation(cell.tile.tileSpec, !cell.isIcon))
true
}
)
@@ -567,24 +591,7 @@ private fun TileGridCell(
)
.tileBackground(colors.background)
) {
- val targetValue = if (cell.isIcon) 0f else 1f
- val animatedProgress = remember { Animatable(targetValue) }
-
- val resizingState = selectionState.resizingState?.takeIf { selected }
- LaunchedEffect(targetValue, resizingState) {
- if (resizingState == null) {
- animatedProgress.animateTo(targetValue)
- } else {
- snapshotFlow { resizingState.progression }
- .collectLatest { animatedProgress.snapTo(it) }
- }
- }
-
- EditTile(
- tile = cell.tile,
- tileWidths = { tileWidths },
- progress = { animatedProgress.value },
- )
+ EditTile(tile = cell.tile, state = state, progress = progress)
}
}
}
@@ -651,7 +658,7 @@ private fun SpacerGridCell(modifier: Modifier = Modifier) {
@Composable
fun EditTile(
tile: EditTileViewModel,
- tileWidths: () -> TileWidths?,
+ state: ResizingState,
progress: () -> Float,
colors: TileColors = EditModeTileDefaults.editTileColors(),
) {
@@ -661,12 +668,16 @@ fun EditTile(
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier.layout { measurable, constraints ->
+ val (min, max) = state.bounds
+ val currentProgress = progress()
// Always display the tile using the large size and trust the parent composable
// to clip the content as needed. This stop the labels from being truncated.
- val width = tileWidths()?.max ?: constraints.maxWidth
+ val width =
+ max?.roundToInt()?.takeIf { it > constraints.maxWidth }
+ ?: constraints.maxWidth
val placeable =
measurable.measure(constraints.copy(minWidth = width, maxWidth = width))
- val currentProgress = progress()
+
val startPadding =
if (currentProgress == 0f) {
// Find the center of the max width when the tile is icon only
@@ -675,7 +686,7 @@ fun EditTile(
// Find the center of the minimum width to hold the same position as the
// tile is resized.
val basePadding =
- tileWidths()?.min?.let { iconHorizontalCenter(it) } ?: 0f
+ min?.let { iconHorizontalCenter(it.roundToInt()) } ?: 0f
// Large tiles, represented with a progress of 1f, have a 0.dp padding
basePadding * (1f - currentProgress)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
index 29ff1715dea2..cb857ae5efc6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
@@ -55,11 +55,7 @@ constructor(
) : PaginatableGridLayout {
@Composable
- override fun SceneScope.TileGrid(
- tiles: List<TileViewModel>,
- modifier: Modifier,
- editModeStart: () -> Unit,
- ) {
+ override fun SceneScope.TileGrid(tiles: List<TileViewModel>, modifier: Modifier) {
DisposableEffect(tiles) {
val token = Any()
tiles.forEach { it.startListening(token) }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt
index 1d36aee4eb85..c6c6dcaa896c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/MutableSelectionState.kt
@@ -27,11 +27,8 @@ import com.android.systemui.qs.pipeline.shared.TileSpec
/** Creates the state of the current selected tile that is remembered across compositions. */
@Composable
-fun rememberSelectionState(
- onResize: (TileSpec) -> Unit,
- onResizeEnd: (TileSpec) -> Unit,
-): MutableSelectionState {
- return remember { MutableSelectionState(onResize, onResizeEnd) }
+fun rememberSelectionState(): MutableSelectionState {
+ return remember { MutableSelectionState() }
}
/**
@@ -41,47 +38,18 @@ fun rememberSelectionState(
data class Selection(val tileSpec: TileSpec, val manual: Boolean)
/** Holds the state of the current selection. */
-class MutableSelectionState(
- val onResize: (TileSpec) -> Unit,
- private val onResizeEnd: (TileSpec) -> Unit,
-) {
+class MutableSelectionState {
private var _selection = mutableStateOf<Selection?>(null)
- private var _resizingState = mutableStateOf<ResizingState?>(null)
/** The [Selection] if a tile is selected, null if not. */
val selection by _selection
- /** The [ResizingState] of the selected tile is currently being resized, null if not. */
- val resizingState by _resizingState
-
fun select(tileSpec: TileSpec, manual: Boolean) {
_selection.value = Selection(tileSpec, manual)
}
fun unSelect() {
_selection.value = null
- onResizingDragEnd()
- }
-
- fun onResizingDrag(offset: Float) {
- _resizingState.value?.onDrag(offset)
- }
-
- fun onResizingDragStart(tileWidths: TileWidths) {
- _selection.value?.let {
- _resizingState.value = ResizingState(tileWidths) { onResize(it.tileSpec) }
- }
- }
-
- fun onResizingDragEnd() {
- _resizingState.value = null
- _selection.value?.let {
- onResizeEnd(it.tileSpec)
-
- // Mark the selection as automatic in case the tile ends up moving to a different
- // row with its new size.
- _selection.value = it.copy(manual = false)
- }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingState.kt
index 41c3de55af70..b27c08077834 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/ResizingState.kt
@@ -16,56 +16,77 @@
package com.android.systemui.qs.panels.ui.compose.selection
+import androidx.compose.foundation.gestures.AnchoredDraggableState
+import androidx.compose.foundation.gestures.DraggableAnchors
+import androidx.compose.foundation.gestures.animateTo
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableFloatStateOf
-import androidx.compose.runtime.mutableIntStateOf
-import androidx.compose.runtime.setValue
-import com.android.systemui.qs.panels.ui.compose.selection.ResizingDefaults.RESIZING_THRESHOLD
+import androidx.compose.runtime.remember
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation.FinalResizeOperation
+import com.android.systemui.qs.panels.ui.compose.selection.ResizingState.ResizeOperation.TemporaryResizeOperation
+import com.android.systemui.qs.pipeline.shared.TileSpec
-class ResizingState(val widths: TileWidths, private val onResize: () -> Unit) {
- /** Total drag offset of this resize operation. */
- private var totalOffset by mutableFloatStateOf(0f)
-
- /** Width in pixels of the resizing tile. */
- var width by mutableIntStateOf(widths.base)
+@Composable
+fun rememberResizingState(tileSpec: TileSpec, startsAsIcon: Boolean): ResizingState {
+ return remember(tileSpec) { ResizingState(tileSpec, startsAsIcon) }
+}
- /** Progression between icon (0) and large (1) sizes. */
- val progression
- get() = calculateProgression()
+enum class QSDragAnchor {
+ Icon,
+ Large,
+}
- // Whether the tile is currently over the threshold and should be a large tile
- private var passedThreshold: Boolean = passedThreshold(progression)
+class ResizingState(tileSpec: TileSpec, startsAsIcon: Boolean) {
+ val anchoredDraggableState =
+ AnchoredDraggableState(if (startsAsIcon) QSDragAnchor.Icon else QSDragAnchor.Large)
- fun onDrag(offset: Float) {
- totalOffset += offset
- width = (widths.base + totalOffset).toInt().coerceIn(widths.min, widths.max)
+ val bounds by derivedStateOf {
+ anchoredDraggableState.anchors.minPosition().takeIf { !it.isNaN() } to
+ anchoredDraggableState.anchors.maxPosition().takeIf { !it.isNaN() }
+ }
- passedThreshold(progression).let {
- // Resize if we went over the threshold
- if (passedThreshold != it) {
- passedThreshold = it
- onResize()
- }
- }
+ val temporaryResizeOperation by derivedStateOf {
+ TemporaryResizeOperation(
+ tileSpec,
+ toIcon = anchoredDraggableState.currentValue == QSDragAnchor.Icon,
+ )
}
- private fun passedThreshold(progression: Float): Boolean {
- return progression >= RESIZING_THRESHOLD
+ val finalResizeOperation by derivedStateOf {
+ FinalResizeOperation(
+ tileSpec,
+ toIcon = anchoredDraggableState.settledValue == QSDragAnchor.Icon,
+ )
}
- /** The progression of the resizing tile between an icon tile (0f) and a large tile (1f) */
- private fun calculateProgression(): Float {
- return ((width - widths.min) / (widths.max - widths.min).toFloat()).coerceIn(0f, 1f)
+ fun updateAnchors(min: Float, max: Float) {
+ anchoredDraggableState.updateAnchors(
+ DraggableAnchors {
+ QSDragAnchor.Icon at min
+ QSDragAnchor.Large at max
+ }
+ )
}
-}
-/** Holds the width of a tile as well as its min and max widths */
-data class TileWidths(val base: Int, val min: Int, val max: Int) {
- init {
- check(max > min) { "The max width needs to be larger than the min width." }
+ suspend fun updateCurrentValue(isIcon: Boolean) {
+ anchoredDraggableState.animateTo(if (isIcon) QSDragAnchor.Icon else QSDragAnchor.Large)
}
-}
-private object ResizingDefaults {
- const val RESIZING_THRESHOLD = .25f
+ fun progress(): Float = anchoredDraggableState.progress(QSDragAnchor.Icon, QSDragAnchor.Large)
+
+ /**
+ * Represents a resizing operation for a tile.
+ *
+ * @property spec The tile's [TileSpec]
+ * @property toIcon The new size for the tile.
+ */
+ sealed class ResizeOperation private constructor(val spec: TileSpec, val toIcon: Boolean) {
+ /** A temporary resizing operation, used while a resizing movement is in motion. */
+ class TemporaryResizeOperation(spec: TileSpec, toIcon: Boolean) :
+ ResizeOperation(spec, toIcon)
+
+ /** A final resizing operation, used while a resizing movement is done. */
+ class FinalResizeOperation(spec: TileSpec, toIcon: Boolean) : ResizeOperation(spec, toIcon)
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
index 8a345ce97c84..a187ff135cbb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
@@ -19,10 +19,10 @@ package com.android.systemui.qs.panels.ui.compose.selection
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
-import androidx.compose.animation.core.animateIntAsState
import androidx.compose.animation.core.spring
import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.gestures.detectHorizontalDragGestures
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.anchoredDraggable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.size
@@ -30,6 +30,7 @@ import androidx.compose.foundation.systemGestureExclusion
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -40,16 +41,15 @@ import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.drawscope.Stroke
-import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize
import androidx.compose.ui.zIndex
-import com.android.compose.modifiers.thenIf
import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.InactiveCornerRadius
import com.android.systemui.qs.panels.ui.compose.selection.SelectionDefaults.ResizingDotSize
import com.android.systemui.qs.panels.ui.compose.selection.SelectionDefaults.SelectedBorderWidth
+import kotlin.math.roundToInt
/**
* Places a dot to handle resizing drag events. Use this on tiles to resize.
@@ -58,31 +58,24 @@ import com.android.systemui.qs.panels.ui.compose.selection.SelectionDefaults.Sel
* selected.
*
* @param selected whether resizing drag events should be handled
- * @param selectionState the [MutableSelectionState] on the grid
+ * @param state the [ResizingState] for the tile
* @param selectionAlpha the animated value for the dot and border alpha
* @param selectionColor the [Color] of the dot and border
- * @param tileWidths the [TileWidths] of the selected tile
*/
@Composable
fun ResizableTileContainer(
selected: Boolean,
- selectionState: MutableSelectionState,
+ state: ResizingState,
selectionAlpha: () -> Float,
selectionColor: Color,
- tileWidths: () -> TileWidths?,
modifier: Modifier = Modifier,
content: @Composable BoxScope.() -> Unit = {},
) {
- Box(
- modifier
- .resizable(selected, selectionState, tileWidths)
- .selectionBorder(selectionColor, selectionAlpha)
- ) {
+ Box(modifier.resizable(selected, state).selectionBorder(selectionColor, selectionAlpha)) {
content()
ResizingHandle(
enabled = selected,
- selectionState = selectionState,
- tileWidths = tileWidths,
+ state = state,
modifier =
// Higher zIndex to make sure the handle is drawn above the content
Modifier.zIndex(2f),
@@ -91,12 +84,7 @@ fun ResizableTileContainer(
}
@Composable
-private fun ResizingHandle(
- enabled: Boolean,
- selectionState: MutableSelectionState,
- tileWidths: () -> TileWidths?,
- modifier: Modifier = Modifier,
-) {
+private fun ResizingHandle(enabled: Boolean, state: ResizingState, modifier: Modifier = Modifier) {
// Manually creating the touch target around the resizing dot to ensure that the next tile
// does not receive the touch input accidentally.
val minTouchTargetSize = LocalMinimumInteractiveComponentSize.current
@@ -112,21 +100,12 @@ private fun ResizingHandle(
)
}
}
- .thenIf(enabled) {
- Modifier.systemGestureExclusion { Rect(Offset.Zero, it.size.toSize()) }
- .pointerInput(Unit) {
- detectHorizontalDragGestures(
- onHorizontalDrag = { _, offset ->
- selectionState.onResizingDrag(offset)
- },
- onDragStart = {
- tileWidths()?.let { selectionState.onResizingDragStart(it) }
- },
- onDragEnd = selectionState::onResizingDragEnd,
- onDragCancel = selectionState::onResizingDragEnd,
- )
- }
- }
+ .systemGestureExclusion { Rect(Offset.Zero, it.size.toSize()) }
+ .anchoredDraggable(
+ enabled = enabled,
+ state = state.anchoredDraggableState,
+ orientation = Orientation.Horizontal,
+ )
) {
ResizingDot(enabled = enabled, modifier = Modifier.align(Alignment.Center))
}
@@ -165,23 +144,15 @@ private fun Modifier.selectionBorder(
}
@Composable
-private fun Modifier.resizable(
- selected: Boolean,
- selectionState: MutableSelectionState,
- tileWidths: () -> TileWidths?,
-): Modifier {
+private fun Modifier.resizable(selected: Boolean, state: ResizingState): Modifier {
if (!selected) return zIndex(1f)
- // Animated diff between the current width and the resized width of the tile. We can't use
- // animateContentSize here as the tile is sometimes unbounded.
- val remainingOffset by
- animateIntAsState(
- selectionState.resizingState?.let { tileWidths()?.base?.minus(it.width) ?: 0 } ?: 0,
- label = "QSEditTileWidthOffset",
- )
return zIndex(2f).layout { measurable, constraints ->
+ val isIdle by derivedStateOf { state.progress().let { it == 0f || it == 1f } }
// Grab the width from the resizing state if a resize is in progress
- val width = selectionState.resizingState?.width ?: (constraints.maxWidth - remainingOffset)
+ val width =
+ state.anchoredDraggableState.requireOffset().roundToInt().takeIf { !isIdle }
+ ?: constraints.maxWidth
val placeable = measurable.measure(constraints.copy(minWidth = width, maxWidth = width))
layout(constraints.maxWidth, placeable.height) { placeable.place(0, 0) }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModel.kt
new file mode 100644
index 000000000000..b033473a91e5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModel.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.systemui.qs.panels.ui.viewmodel
+
+import com.android.systemui.classifier.domain.interactor.FalsingInteractor
+import com.android.systemui.plugins.FalsingManager
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+class EditModeButtonViewModel
+@AssistedInject
+constructor(
+ private val editModeViewModel: EditModeViewModel,
+ private val falsingInteractor: FalsingInteractor,
+) {
+
+ fun onButtonClick() {
+ if (!falsingInteractor.isFalseTap(FalsingManager.LOW_PENALTY)) {
+ editModeViewModel.startEditing()
+ }
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(): EditModeButtonViewModel
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
index bff330b98fda..4a18872ad6f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
@@ -17,6 +17,8 @@
package com.android.systemui.qs.panels.ui.viewmodel
import androidx.compose.runtime.getValue
+import com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE
+import com.android.systemui.classifier.domain.interactor.FalsingInteractor
import com.android.systemui.development.ui.viewmodel.BuildNumberViewModel
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
@@ -36,6 +38,8 @@ constructor(
paginatedGridInteractor: PaginatedGridInteractor,
inFirstPageViewModel: InFirstPageViewModel,
val buildNumberViewModelFactory: BuildNumberViewModel.Factory,
+ val editModeButtonViewModelFactory: EditModeButtonViewModel.Factory,
+ private val falsingInteractor: FalsingInteractor,
) : IconTilesViewModel by iconTilesViewModel, ExclusiveActivatable() {
private val hydrator = Hydrator("PaginatedGridViewModel")
@@ -53,6 +57,10 @@ constructor(
val columns: Int
get() = columnsWithMediaViewModel.columns
+ fun registerSideSwipeGesture() {
+ falsingInteractor.isFalseTouch(QS_SWIPE_SIDE)
+ }
+
override suspend fun onActivated(): Nothing {
coroutineScope {
launch { hydrator.activate() }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 1fb76f1eaa7f..b7ebce247ec9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -27,6 +27,7 @@ import android.content.res.Resources.ID_NULL
import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.Rect
+import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.LayerDrawable
@@ -308,6 +309,14 @@ constructor(
}
setLabelColor(getLabelColorForState(QSTile.State.DEFAULT_STATE))
setSecondaryLabelColor(getSecondaryLabelColorForState(QSTile.State.DEFAULT_STATE))
+
+ if (Flags.gsfQuickSettings()) {
+ label.apply {
+ typeface = Typeface.create("gsf-title-small-emphasized", Typeface.NORMAL)
+ }
+ secondaryLabel.apply { typeface = Typeface.create("gsf-label-medium", Typeface.NORMAL) }
+ }
+
addView(labelContainer)
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractor.kt
new file mode 100644
index 000000000000..d7c3b6b43c71
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractor.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.scene.domain.interactor
+
+import com.android.compose.animation.scene.ContentKey
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
+import com.android.systemui.scene.shared.model.Overlays
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.statusbar.disableflags.domain.interactor.DisableFlagsInteractor
+import com.android.systemui.statusbar.disableflags.shared.model.DisableFlagsModel
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+
+class DisabledContentInteractor
+@Inject
+constructor(private val disableFlagsInteractor: DisableFlagsInteractor) {
+
+ /** Returns `true` if the given [key] is disabled; `false` if it's enabled */
+ fun isDisabled(
+ key: ContentKey,
+ disabledFlags: DisableFlagsModel = disableFlagsInteractor.disableFlags.value,
+ ): Boolean {
+ return with(disabledFlags) {
+ when (key) {
+ Scenes.Shade,
+ Overlays.NotificationsShade -> !isShadeEnabled()
+ Scenes.QuickSettings,
+ Overlays.QuickSettingsShade -> !isQuickSettingsEnabled()
+ else -> false
+ }
+ }
+ }
+
+ /** Runs the given [block] each time that [key] becomes disabled. */
+ suspend fun repeatWhenDisabled(key: ContentKey, block: suspend (disabled: ContentKey) -> Unit) {
+ disableFlagsInteractor.disableFlags
+ .map { isDisabled(key) }
+ .distinctUntilChanged()
+ .collectLatest { isDisabled ->
+ if (isDisabled) {
+ block(key)
+ }
+ }
+ }
+
+ /**
+ * Returns a filtered version of [unfiltered], without action-result entries that would navigate
+ * to disabled scenes.
+ */
+ fun filteredUserActions(
+ unfiltered: Flow<Map<UserAction, UserActionResult>>
+ ): Flow<Map<UserAction, UserActionResult>> {
+ return combine(disableFlagsInteractor.disableFlags, unfiltered) {
+ disabledFlags,
+ unfilteredMap ->
+ unfilteredMap.filterValues { actionResult ->
+ val destination =
+ when (actionResult) {
+ is UserActionResult.ChangeScene -> actionResult.toScene
+ is UserActionResult.ShowOverlay -> actionResult.overlay
+ is UserActionResult.ReplaceByOverlay -> actionResult.overlay
+ else -> null
+ }
+ if (destination != null) {
+ // results that lead to a disabled destination get filtered out.
+ !isDisabled(key = destination, disabledFlags = disabledFlags)
+ } else {
+ // Action results that don't lead to a destination are never filtered out.
+ true
+ }
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index f20e5a54f6ed..d83d74e4e538 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -21,6 +21,8 @@ import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionKey
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
@@ -64,6 +66,7 @@ constructor(
private val sceneFamilyResolvers: Lazy<Map<SceneKey, @JvmSuppressWildcards SceneResolver>>,
private val deviceUnlockedInteractor: Lazy<DeviceUnlockedInteractor>,
private val keyguardEnabledInteractor: Lazy<KeyguardEnabledInteractor>,
+ private val disabledContentInteractor: DisabledContentInteractor,
) {
interface OnSceneAboutToChangeListener {
@@ -465,6 +468,10 @@ constructor(
return false
}
+ if (disabledContentInteractor.isDisabled(to)) {
+ return false
+ }
+
val inMidTransitionFromGone =
(transitionState.value as? ObservableTransitionState.Transition)?.fromContent ==
Scenes.Gone
@@ -503,6 +510,10 @@ constructor(
" Logging reason for overlay change was: $loggingReason"
}
+ if (to != null && disabledContentInteractor.isDisabled(to)) {
+ return false
+ }
+
val isFromValid = (from == null) || (from in currentOverlays.value)
val isToValid =
(to == null) || (to !in currentOverlays.value && to in repository.allContentKeys)
@@ -517,4 +528,14 @@ constructor(
/** Returns `true` if [scene] can be resolved from [family]. */
fun isSceneInFamily(scene: SceneKey, family: SceneKey): Boolean =
sceneFamilyResolvers.get()[family]?.includesScene(scene) == true
+
+ /**
+ * Returns a filtered version of [unfiltered], without action-result entries that would navigate
+ * to disabled scenes.
+ */
+ fun filteredUserActions(
+ unfiltered: Flow<Map<UserAction, UserActionResult>>
+ ): Flow<Map<UserAction, UserActionResult>> {
+ return disabledContentInteractor.filteredUserActions(unfiltered)
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index aece5c65ce12..8d8c24eae9e2 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -19,7 +19,6 @@
package com.android.systemui.scene.domain.startable
import android.app.StatusBarManager
-import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.internal.logging.UiEventLogger
@@ -56,6 +55,7 @@ import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.shared.model.WakeSleepReason
import com.android.systemui.scene.data.model.asIterable
import com.android.systemui.scene.data.model.sceneStackOf
+import com.android.systemui.scene.domain.interactor.DisabledContentInteractor
import com.android.systemui.scene.domain.interactor.SceneBackInteractor
import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
@@ -103,6 +103,7 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
/**
* Hooks up business logic that manipulates the state of the [SceneInteractor] for the system UI
@@ -144,6 +145,7 @@ constructor(
private val alternateBouncerInteractor: AlternateBouncerInteractor,
private val vibratorHelper: VibratorHelper,
private val msdlPlayer: MSDLPlayer,
+ private val disabledContentInteractor: DisabledContentInteractor,
) : CoreStartable {
private val centralSurfaces: CentralSurfaces?
get() = centralSurfacesOptLazy.get().getOrNull()
@@ -281,6 +283,7 @@ constructor(
handlePowerState()
handleDreamState()
handleShadeTouchability()
+ handleDisableFlags()
}
private fun handleBouncerImeVisibility() {
@@ -565,6 +568,38 @@ constructor(
}
}
+ private fun handleDisableFlags() {
+ applicationScope.launch {
+ launch {
+ sceneInteractor.currentScene.collectLatest { currentScene ->
+ disabledContentInteractor.repeatWhenDisabled(currentScene) {
+ switchToScene(
+ targetSceneKey = SceneFamilies.Home,
+ loggingReason =
+ "Current scene ${currentScene.debugName} became" + " disabled",
+ )
+ }
+ }
+ }
+
+ launch {
+ sceneInteractor.currentOverlays.collectLatest { overlays ->
+ overlays.forEach { overlay ->
+ launch {
+ disabledContentInteractor.repeatWhenDisabled(overlay) {
+ sceneInteractor.hideOverlay(
+ overlay = overlay,
+ loggingReason =
+ "Overlay ${overlay.debugName} became" + " disabled",
+ )
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
private fun handleDeviceEntryHapticsWhileDeviceLocked() {
applicationScope.launch {
deviceEntryInteractor.isDeviceEntered.collectLatest { isDeviceEntered ->
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
index 32d5cb460cd8..c1e8032aa9e5 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
@@ -280,6 +280,16 @@ constructor(
}
}
+ /**
+ * Returns a filtered version of [unfiltered], without action-result entries that would navigate
+ * to disabled scenes.
+ */
+ fun filteredUserActions(
+ unfiltered: Flow<Map<UserAction, UserActionResult>>
+ ): Flow<Map<UserAction, UserActionResult>> {
+ return sceneInteractor.filteredUserActions(unfiltered)
+ }
+
/** Defines interface for classes that can handle externally-reported [MotionEvent]s. */
interface MotionEventHandler {
/** Notifies that a [MotionEvent] has occurred. */
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
index 4f73a3456cad..0b36e685d914 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeDisplayAwareModule.kt
@@ -17,9 +17,9 @@
package com.android.systemui.shade
import android.content.Context
+import android.content.MutableContextWrapper
import android.content.res.Resources
import android.view.LayoutInflater
-import android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
import com.android.systemui.CoreStartable
import com.android.systemui.common.ui.ConfigurationState
import com.android.systemui.common.ui.ConfigurationStateImpl
@@ -29,17 +29,20 @@ import com.android.systemui.common.ui.data.repository.ConfigurationRepositoryImp
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractorImpl
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.res.R
+import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
import com.android.systemui.shade.data.repository.ShadeDisplaysRepositoryImpl
+import com.android.systemui.shade.domain.interactor.ShadeDisplaysInteractor
import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl
import com.android.systemui.statusbar.phone.ConfigurationForwarder
import com.android.systemui.statusbar.policy.ConfigurationController
+import dagger.BindsOptionalOf
import dagger.Module
import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
+import javax.inject.Provider
/**
* Module responsible for managing display-specific components and resources for the notification
@@ -53,7 +56,7 @@ import dagger.multibindings.IntoMap
* By using this dedicated module, we ensure the notification shade window always utilizes the
* correct display context and resources, regardless of the display it's on.
*/
-@Module
+@Module(includes = [OptionalShadeDisplayAwareBindings::class])
object ShadeDisplayAwareModule {
/** Creates a new context for the shade window. */
@@ -62,9 +65,7 @@ object ShadeDisplayAwareModule {
@SysUISingleton
fun provideShadeDisplayAwareContext(context: Context): Context {
return if (ShadeWindowGoesAround.isEnabled) {
- context
- .createWindowContext(context.display, TYPE_APPLICATION_OVERLAY, /* options= */ null)
- .apply { setTheme(R.style.Theme_SystemUI) }
+ MutableContextWrapper(context)
} else {
context
}
@@ -172,4 +173,20 @@ object ShadeDisplayAwareModule {
CoreStartable.NOP
}
}
+
+ @Provides
+ @IntoMap
+ @ClassKey(ShadeDisplaysInteractor::class)
+ fun provideShadeDisplaysInteractor(impl: Provider<ShadeDisplaysInteractor>): CoreStartable {
+ return if (ShadeWindowGoesAround.isEnabled) {
+ impl.get()
+ } else {
+ CoreStartable.NOP
+ }
+ }
+}
+
+@Module
+internal interface OptionalShadeDisplayAwareBindings {
+ @BindsOptionalOf fun bindOptionalOfWindowRootView(): WindowRootView
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
index 1055dcb55d5f..432d5f553fbb 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeDisplaysInteractor.kt
@@ -16,8 +16,13 @@
package com.android.systemui.shade.domain.interactor
+import android.content.ComponentCallbacks
import android.content.Context
+import android.content.MutableContextWrapper
+import android.content.res.Configuration
+import android.content.res.Resources
import android.util.Log
+import android.view.WindowManager
import android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE
import com.android.app.tracing.coroutines.launchTraced
import com.android.app.tracing.traceSection
@@ -33,6 +38,8 @@ import com.android.systemui.shade.ShadeWindowLayoutParams
import com.android.systemui.shade.data.repository.ShadeDisplaysRepository
import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
import com.android.systemui.statusbar.phone.ConfigurationForwarder
+import com.android.systemui.util.kotlin.getOrNull
+import java.util.Optional
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
@@ -43,15 +50,29 @@ import kotlinx.coroutines.withContext
class ShadeDisplaysInteractor
@Inject
constructor(
- private val shadeRootView: WindowRootView,
+ optionalShadeRootView: Optional<WindowRootView>,
private val shadePositionRepository: ShadeDisplaysRepository,
@ShadeDisplayAware private val shadeContext: Context,
+ @ShadeDisplayAware private val shadeResources: Resources,
private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
@Background private val bgScope: CoroutineScope,
- @ShadeDisplayAware private val configurationForwarder: ConfigurationForwarder,
- @Main private val mainContext: CoroutineContext,
+ @ShadeDisplayAware private val shadeConfigurationForwarder: ConfigurationForwarder,
+ @Main private val mainThreadContext: CoroutineContext,
) : CoreStartable {
+ private val shadeRootView =
+ optionalShadeRootView.getOrNull()
+ ?: error(
+ """
+ ShadeRootView must be provided for this ShadeDisplayInteractor to work.
+ If it is not, it means this is being instantiated in a SystemUI variant that shouldn't.
+ """
+ .trimIndent()
+ )
+ // TODO: b/362719719 - Get rid of this callback as the root view should automatically get the
+ // correct configuration once it's moved to another window.
+ private var unregisterConfigChangedCallbacks: (() -> Unit)? = null
+
override fun start() {
ShadeWindowGoesAround.isUnexpectedlyInLegacyMode()
bgScope.launchTraced(TAG) {
@@ -60,43 +81,86 @@ constructor(
}
/** Tries to move the shade. If anything wrong happens, fails gracefully without crashing. */
- private suspend fun moveShadeWindowTo(destinationDisplayId: Int) {
- val currentId = shadeRootView.display.displayId
- if (currentId == destinationDisplayId) {
+ private suspend fun moveShadeWindowTo(destinationId: Int) {
+ Log.d(TAG, "Trying to move shade window to display with id $destinationId")
+ val currentDisplay = shadeRootView.display
+ if (currentDisplay == null) {
+ Log.w(TAG, "Current shade display is null")
+ return
+ }
+ val currentId = currentDisplay.displayId
+ if (currentId == destinationId) {
Log.w(TAG, "Trying to move the shade to a display it was already in")
return
}
try {
- moveShadeWindow(fromId = currentId, toId = destinationDisplayId)
+ moveShadeWindow(fromId = currentId, toId = destinationId)
} catch (e: IllegalStateException) {
Log.e(
TAG,
- "Unable to move the shade window from display $currentId to $destinationDisplayId",
+ "Unable to move the shade window from display $currentId to $destinationId",
e,
)
}
}
private suspend fun moveShadeWindow(fromId: Int, toId: Int) {
- val sourceProperties = getDisplayWindowProperties(fromId)
- val destinationProperties = getDisplayWindowProperties(toId)
- traceSection({ "MovingShadeWindow from $fromId to $toId" }) {
- withContext(mainContext) {
- traceSection("removeView") {
- sourceProperties.windowManager.removeView(shadeRootView)
- }
- traceSection("addView") {
- destinationProperties.windowManager.addView(
- shadeRootView,
- ShadeWindowLayoutParams.create(shadeContext),
- )
- }
+ val (_, _, _, sourceWm) = getDisplayWindowProperties(fromId)
+ val (_, _, destContext, destWm) = getDisplayWindowProperties(toId)
+ withContext(mainThreadContext) {
+ traceSection({ "MovingShadeWindow from $fromId to $toId" }) {
+ removeShade(sourceWm)
+ addShade(destWm)
+ overrideContextAndResources(newContext = destContext)
+ registerConfigurationChange(destContext)
+ }
+ traceSection("ShadeDisplaysInteractor#onConfigurationChanged") {
+ dispatchConfigurationChanged(destContext.resources.configuration)
}
}
- traceSection("SecondaryShadeInteractor#onConfigurationChanged") {
- configurationForwarder.onConfigurationChanged(
- destinationProperties.context.resources.configuration
- )
+ }
+
+ private fun removeShade(wm: WindowManager): Unit =
+ traceSection("removeView") { wm.removeView(shadeRootView) }
+
+ private fun addShade(wm: WindowManager): Unit =
+ traceSection("addView") {
+ wm.addView(shadeRootView, ShadeWindowLayoutParams.create(shadeContext))
+ }
+
+ private fun overrideContextAndResources(newContext: Context) {
+ val contextWrapper =
+ shadeContext as? MutableContextWrapper
+ ?: error("Shade context is not a MutableContextWrapper!")
+ contextWrapper.baseContext = newContext
+ // Override needed in case someone is keeping a reference to the resources from the old
+ // context.
+ // TODO: b/362719719 - This shouldn't be needed, as resources should be updated when the
+ // window is moved to the new display automatically.
+ shadeResources.impl = shadeContext.resources.impl
+ }
+
+ private fun dispatchConfigurationChanged(newConfig: Configuration) {
+ shadeConfigurationForwarder.onConfigurationChanged(newConfig)
+ shadeRootView.dispatchConfigurationChanged(newConfig)
+ shadeRootView.requestLayout()
+ }
+
+ private fun registerConfigurationChange(context: Context) {
+ // we should keep only one at the time.
+ unregisterConfigChangedCallbacks?.invoke()
+ val callback =
+ object : ComponentCallbacks {
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ dispatchConfigurationChanged(newConfig)
+ }
+
+ override fun onLowMemory() {}
+ }
+ context.registerComponentCallbacks(callback)
+ unregisterConfigChangedCallbacks = {
+ context.unregisterComponentCallbacks(callback)
+ unregisterConfigChangedCallbacks = null
}
}
@@ -105,6 +169,6 @@ constructor(
}
private companion object {
- const val TAG = "SecondaryShadeInteractor"
+ const val TAG = "ShadeDisplaysInteractor"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
index 45516aa69cd7..0d847d84c820 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModel.kt
@@ -23,6 +23,7 @@ import android.icu.text.DateFormat
import android.icu.text.DisplayContext
import android.os.UserHandle
import android.provider.Settings
+import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.plugins.ActivityStarter
@@ -48,7 +49,6 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
/** Models UI state for the shade header. */
class ShadeHeaderViewModel
@@ -87,10 +87,6 @@ constructor(
/** Whether or not the privacy chip is enabled in the device privacy config. */
val isPrivacyChipEnabled: StateFlow<Boolean> = privacyChipInteractor.isChipEnabled
- private val _isDisabled = MutableStateFlow(false)
- /** Whether or not the Shade Header should be disabled based on disableFlags. */
- val isDisabled: StateFlow<Boolean> = _isDisabled.asStateFlow()
-
private val longerPattern = context.getString(R.string.abbrev_wday_month_day_no_year_alarm)
private val shorterPattern = context.getString(R.string.abbrev_month_day_no_year)
private val longerDateFormat = MutableStateFlow(getFormatFromPattern(longerPattern))
@@ -132,8 +128,6 @@ constructor(
.collect { _mobileSubIds.value = it }
}
- launch { shadeInteractor.isQsEnabled.map { !it }.collect { _isDisabled.value = it } }
-
awaitCancellation()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt
index b0777c9e20b9..dd1b58c47b63 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeUserActions.kt
@@ -27,24 +27,28 @@ import com.android.systemui.scene.ui.viewmodel.SceneContainerEdge
/** Returns collection of [UserAction] to [UserActionResult] pairs for opening the single shade. */
fun singleShadeActions(
- requireTwoPointersForTopEdgeForQs: Boolean = false
+ isDownFromTopEdgeEnabled: Boolean = true,
+ requireTwoPointersForTopEdgeForQs: Boolean = false,
): Array<Pair<UserAction, UserActionResult>> {
val shadeUserActionResult = UserActionResult(Scenes.Shade, isIrreversible = true)
val qsSceneUserActionResult = UserActionResult(Scenes.QuickSettings, isIrreversible = true)
- return arrayOf(
- // Swiping down, not from the edge, always goes to shade.
- Swipe.Down to shadeUserActionResult,
- Swipe.Down(pointerCount = 2) to shadeUserActionResult,
-
- // Swiping down from the top edge.
- swipeDownFromTop(pointerCount = 1) to
- if (requireTwoPointersForTopEdgeForQs) {
- shadeUserActionResult
- } else {
- qsSceneUserActionResult
- },
- swipeDownFromTop(pointerCount = 2) to qsSceneUserActionResult,
- )
+ return buildList {
+ // Swiping down, not from the edge, always goes to shade.
+ add(Swipe.Down to shadeUserActionResult)
+ add(Swipe.Down(pointerCount = 2) to shadeUserActionResult)
+ if (isDownFromTopEdgeEnabled) {
+ add(
+ swipeDownFromTop(pointerCount = 1) to
+ if (requireTwoPointersForTopEdgeForQs) {
+ shadeUserActionResult
+ } else {
+ qsSceneUserActionResult
+ }
+ )
+ add(swipeDownFromTop(pointerCount = 2) to qsSceneUserActionResult)
+ }
+ }
+ .toTypedArray()
}
/** Returns collection of [UserAction] to [UserActionResult] pairs for opening the split shade. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
index af238f697a18..49c44798d2ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.chips.mediaprojection.domain.interactor
import android.content.pm.PackageManager
+import android.media.projection.StopReason
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.Flags
import com.android.systemui.dagger.SysUISingleton
@@ -105,7 +106,7 @@ constructor(
/** Stops the currently active projection. */
fun stopProjecting() {
- scope.launch { mediaProjectionRepository.stopProjecting() }
+ scope.launch { mediaProjectionRepository.stopProjecting(StopReason.STOP_PRIVACY_CHIP) }
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt
index 434120051039..9b24d451f9cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.kt
@@ -27,6 +27,8 @@ import com.android.systemui.log.LogBufferFactory
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.data.StatusBarDataLayerModule
import com.android.systemui.statusbar.data.repository.LightBarControllerStore
+import com.android.systemui.statusbar.phone.AutoHideController
+import com.android.systemui.statusbar.phone.AutoHideControllerImpl
import com.android.systemui.statusbar.phone.LightBarController
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProviderImpl
@@ -79,6 +81,8 @@ interface StatusBarModule {
implFactory: StatusBarWindowControllerImpl.Factory
): StatusBarWindowController.Factory
+ @Binds @SysUISingleton fun autoHideController(impl: AutoHideControllerImpl): AutoHideController
+
companion object {
@Provides
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
index 47a04291dd49..733b986b5422 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinator.java
@@ -20,13 +20,21 @@ import static android.app.NotificationManager.IMPORTANCE_MIN;
import android.app.Notification;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
import com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt;
+import com.google.common.primitives.Booleans;
+
import javax.inject.Inject;
/**
@@ -44,12 +52,21 @@ public class ColorizedFgsCoordinator implements Coordinator {
@Override
public void attach(NotifPipeline pipeline) {
+ if (PromotedNotificationUi.isEnabled()) {
+ pipeline.addPromoter(mPromotedOngoingPromoter);
+ }
}
public NotifSectioner getSectioner() {
return mNotifSectioner;
}
+ private final NotifPromoter mPromotedOngoingPromoter = new NotifPromoter("PromotedOngoing") {
+ @Override
+ public boolean shouldPromoteToTopLevel(NotificationEntry child) {
+ return isPromotedOngoing(child);
+ }
+ };
/**
* Puts colorized foreground service and call notifications into its own section.
@@ -64,11 +81,30 @@ public class ColorizedFgsCoordinator implements Coordinator {
}
return false;
}
+
+ private NotifComparator mPreferPromoted = new NotifComparator("PreferPromoted") {
+ @Override
+ public int compare(@NonNull ListEntry o1, @NonNull ListEntry o2) {
+ return -1 * Booleans.compare(
+ isPromotedOngoing(o1.getRepresentativeEntry()),
+ isPromotedOngoing(o2.getRepresentativeEntry()));
+ }
+ };
+
+ @Nullable
+ @Override
+ public NotifComparator getComparator() {
+ if (PromotedNotificationUi.isEnabled()) {
+ return mPreferPromoted;
+ } else {
+ return null;
+ }
+ }
};
/** Determines if the given notification is a colorized or call notification */
public static boolean isRichOngoing(NotificationEntry entry) {
- return isColorizedForegroundService(entry) || isCall(entry);
+ return isPromotedOngoing(entry) || isColorizedForegroundService(entry) || isCall(entry);
}
private static boolean isColorizedForegroundService(NotificationEntry entry) {
@@ -78,6 +114,11 @@ public class ColorizedFgsCoordinator implements Coordinator {
&& entry.getImportance() > IMPORTANCE_MIN;
}
+ private static boolean isPromotedOngoing(NotificationEntry entry) {
+ // NOTE: isPromotedOngoing already checks the android.app.ui_rich_ongoing flag.
+ return entry != null && entry.getSbn().getNotification().isPromotedOngoing();
+ }
+
private static boolean isCall(NotificationEntry entry) {
Notification notification = entry.getSbn().getNotification();
return entry.getImportance() > IMPORTANCE_MIN
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index a90a1053e01c..0480212e4d59 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -36,6 +36,7 @@ import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.Point;
+import android.graphics.Rect;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
@@ -108,6 +109,7 @@ import com.android.systemui.statusbar.notification.row.shared.AsyncGroupHeaderVi
import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationCompactMessagingTemplateViewWrapper;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
+import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
import com.android.systemui.statusbar.notification.shared.TransparentHeaderFix;
import com.android.systemui.statusbar.notification.stack.AmbientState;
@@ -125,6 +127,7 @@ import com.android.systemui.statusbar.policy.SmartReplyConstants;
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
import com.android.systemui.util.Compile;
import com.android.systemui.util.DumpUtilsKt;
+import com.android.systemui.util.ListenerSet;
import com.android.systemui.wmshell.BubblesManager;
import java.io.PrintWriter;
@@ -430,6 +433,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private float mBottomRoundnessDuringLaunchAnimation;
private float mSmallRoundness;
+ private ListenerSet<DismissButtonTargetVisibilityListener>
+ mDismissButtonTargetVisibilityListeners
+ = new ListenerSet();
+
public NotificationContentView[] getLayouts() {
return Arrays.copyOf(mLayouts, mLayouts.length);
}
@@ -739,6 +746,73 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
}
+ public interface DismissButtonTargetVisibilityListener {
+ // Called when the notification dismiss button's target visibility changes.
+ // NOTE: This can be called when the dismiss button already has the target visibility.
+ void onTargetVisibilityChanged(boolean targetVisible);
+ }
+
+ public void addDismissButtonTargetStateListener(
+ DismissButtonTargetVisibilityListener listener) {
+ if (NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode()) {
+ return;
+ }
+
+ mDismissButtonTargetVisibilityListeners.addIfAbsent(listener);
+ }
+
+ public void removeDismissButtonTargetStateListener(
+ DismissButtonTargetVisibilityListener listener) {
+ if (NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode()) {
+ return;
+ }
+
+ mDismissButtonTargetVisibilityListeners.remove(listener);
+ }
+
+ @Override
+ public boolean onInterceptHoverEvent(MotionEvent event) {
+ if (!NotificationAddXOnHoverToDismiss.isEnabled()) {
+ return super.onInterceptHoverEvent(event);
+ }
+
+ // Do not bother checking the dismiss button's target visibility if the notification cannot
+ // be dismissed.
+ if (!canEntryBeDismissed()) {
+ return false;
+ }
+
+ final Boolean targetVisible = getDismissButtonTargetVisibilityIfAny(event);
+ if (targetVisible != null) {
+ for (DismissButtonTargetVisibilityListener listener :
+ mDismissButtonTargetVisibilityListeners) {
+ listener.onTargetVisibilityChanged(targetVisible.booleanValue());
+ }
+ }
+
+ // Do not consume the hover event so that children still have a chance to process it.
+ return false;
+ }
+
+ private @Nullable Boolean getDismissButtonTargetVisibilityIfAny(MotionEvent event) {
+ // Returns the dismiss button's target visibility resulted by `event`. Returns null if the
+ // target visibility should not change.
+
+ if (event.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
+ // The notification dismiss button should be hidden when the hover exit event is located
+ // outside of the notification. NOTE: The hover exit event can be inside the
+ // notification if hover moves from one hoverable child to another.
+ final Rect localBounds = new Rect(0, 0, this.getWidth(), this.getActualHeight());
+ if (!localBounds.contains((int) event.getX(), (int) event.getY())) {
+ return Boolean.FALSE;
+ }
+ } else if (event.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
+ return Boolean.TRUE;
+ }
+
+ return null;
+ }
+
private void updateLimitsForView(NotificationContentView layout) {
View contractedView = layout.getContractedChild();
boolean customView = contractedView != null
@@ -1536,6 +1610,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mPrivateLayout.getSingleLineView();
}
+ /**
+ * Whether this row is displayed over the unoccluded lockscreen. Returns false on the
+ * locked shade.
+ */
public boolean isOnKeyguard() {
return mOnKeyguard;
}
@@ -2214,6 +2292,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mTranslateableViews.remove(mGutsStub);
// We don't handle focus highlight in this view, it's done in background drawable instead
setDefaultFocusHighlightEnabled(false);
+
+ if (NotificationAddXOnHoverToDismiss.isEnabled()) {
+ addDismissButtonTargetStateListener(findViewById(R.id.backgroundNormal));
+ }
}
/**
@@ -2820,7 +2902,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
}
- void setOnKeyguard(boolean onKeyguard) {
+ /** @see #isOnKeyguard() */
+ public void setOnKeyguard(boolean onKeyguard) {
if (onKeyguard != mOnKeyguard) {
boolean wasAboveShelf = isAboveShelf();
final boolean wasExpanded = isExpanded();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index baad616cbf02..ffe1b6f88302 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -41,6 +41,7 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.ColorUpdateLogger;
import com.android.systemui.statusbar.notification.FeedbackIcon;
@@ -378,15 +379,19 @@ public class ExpandableNotificationRowController implements NotifViewController
mView.getEntry().setInitializationTime(mClock.elapsedRealtime());
mPluginManager.addPluginListener(mView,
NotificationMenuRowPlugin.class, false /* Allow multiple */);
- mView.setOnKeyguard(mStatusBarStateController.getState() == KEYGUARD);
- mStatusBarStateController.addCallback(mStatusBarStateListener);
+ if (!SceneContainerFlag.isEnabled()) {
+ mView.setOnKeyguard(mStatusBarStateController.getState() == KEYGUARD);
+ mStatusBarStateController.addCallback(mStatusBarStateListener);
+ }
mSettingsController.addCallback(BUBBLES_SETTING_URI, mSettingsListener);
}
@Override
public void onViewDetachedFromWindow(View v) {
mPluginManager.removePluginListener(mView);
- mStatusBarStateController.removeCallback(mStatusBarStateListener);
+ if (!SceneContainerFlag.isEnabled()) {
+ mStatusBarStateController.removeCallback(mStatusBarStateListener);
+ }
mSettingsController.removeCallback(BUBBLES_SETTING_URI, mSettingsListener);
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index d0db5145e0ff..34ef63944f14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -21,7 +21,9 @@ import static com.android.systemui.util.ColorUtilKt.hexColorString;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
+import android.graphics.Path;
import android.graphics.PorterDuff;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
@@ -36,6 +38,7 @@ import com.android.internal.util.ContrastColorUtil;
import com.android.settingslib.Utils;
import com.android.systemui.Dumpable;
import com.android.systemui.res.R;
+import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
import com.android.systemui.util.DrawableDumpKt;
import java.io.PrintWriter;
@@ -44,7 +47,8 @@ import java.util.Arrays;
/**
* A view that can be used for both the dimmed and normal background of an notification.
*/
-public class NotificationBackgroundView extends View implements Dumpable {
+public class NotificationBackgroundView extends View implements Dumpable,
+ ExpandableNotificationRow.DismissButtonTargetVisibilityListener {
private final boolean mDontModifyCorners;
private Drawable mBackground;
@@ -66,6 +70,11 @@ public class NotificationBackgroundView extends View implements Dumpable {
private final ColorStateList mLightColoredStatefulColors;
private final ColorStateList mDarkColoredStatefulColors;
private final int mNormalColor;
+ private final int convexR = 9;
+ private final int concaveR = 22;
+
+ // True only if the dismiss button is visible.
+ private boolean mDrawDismissButtonCutout = false;
public NotificationBackgroundView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -80,6 +89,18 @@ public class NotificationBackgroundView extends View implements Dumpable {
}
@Override
+ public void onTargetVisibilityChanged(boolean targetVisible) {
+ if (NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode()) {
+ return;
+ }
+
+ if (mDrawDismissButtonCutout != targetVisible) {
+ mDrawDismissButtonCutout = targetVisible;
+ invalidate();
+ }
+ }
+
+ @Override
protected void onDraw(Canvas canvas) {
if (mClipTopAmount + mClipBottomAmount < getActualHeight() || mExpandAnimationRunning) {
canvas.save();
@@ -87,12 +108,87 @@ public class NotificationBackgroundView extends View implements Dumpable {
canvas.clipRect(0, mClipTopAmount, getWidth(),
getActualHeight() - mClipBottomAmount);
}
- draw(canvas, mBackground);
+
+ if (!NotificationAddXOnHoverToDismiss.isEnabled()) {
+ draw(canvas, mBackground);
+ canvas.restore();
+ return;
+ }
+
+ Rect backgroundBounds = null;
+ if (mBackground != null || mDrawDismissButtonCutout) {
+ backgroundBounds = calculateBackgroundBounds();
+ }
+
+ if (mDrawDismissButtonCutout) {
+ canvas.clipPath(calculateDismissButtonCutoutPath(backgroundBounds));
+ }
+
+ if (mBackground != null) {
+ mBackground.setBounds(backgroundBounds);
+ mBackground.draw(canvas);
+ }
+
canvas.restore();
}
}
+ private Path calculateDismissButtonCutoutPath(Rect backgroundBounds) {
+ // TODO(b/365585705): Adapt to RTL after the UX design is finalized.
+
+ NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode();
+
+ Path path = new Path();
+
+ final int left = backgroundBounds.left;
+ final int right = backgroundBounds.right;
+ final int top = backgroundBounds.top;
+ final int bottom = backgroundBounds.bottom;
+
+ // Generate the path clockwise from the left-top corner.
+ path.moveTo(left, top);
+ path.lineTo(right - 2 * convexR - concaveR, top);
+ path.quadTo(right - convexR - concaveR, top, right - convexR - concaveR,
+ top + convexR);
+ path.quadTo(right - convexR - concaveR, top + convexR + concaveR, right - convexR,
+ top + convexR + concaveR);
+ path.quadTo(right, top + convexR + concaveR, right, top + 2 * convexR + concaveR);
+ path.lineTo(right, bottom);
+ path.lineTo(left, bottom);
+ path.lineTo(left, top);
+
+ return path;
+ }
+
+ private Rect calculateBackgroundBounds() {
+ NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode();
+
+ int top = 0;
+ int bottom = getActualHeight();
+ if (mBottomIsRounded
+ && mBottomAmountClips
+ && !mExpandAnimationRunning) {
+ bottom -= mClipBottomAmount;
+ }
+ final boolean isRtl = isLayoutRtl();
+ final int width = getWidth();
+ final int actualWidth = getActualWidth();
+
+ int left = isRtl ? width - actualWidth : 0;
+ int right = isRtl ? width : actualWidth;
+
+ if (mExpandAnimationRunning) {
+ // Horizontally center this background view inside of the container
+ left = (int) ((width - actualWidth) / 2.0f);
+ right = (int) (left + actualWidth);
+ }
+
+ return new Rect(left, top, right, bottom);
+ }
+
private void draw(Canvas canvas, Drawable drawable) {
+ NotificationAddXOnHoverToDismiss.assertInLegacyMode();
+
if (drawable != null) {
int top = 0;
int bottom = getActualHeight();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index b622defbef98..e9eecdd8a26f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -16,6 +16,9 @@
package com.android.systemui.statusbar.notification.row.wrapper;
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
import android.app.Notification;
@@ -48,6 +51,7 @@ import com.android.systemui.statusbar.notification.Roundable;
import com.android.systemui.statusbar.notification.RoundableState;
import com.android.systemui.statusbar.notification.TransformState;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
import java.util.Stack;
@@ -115,6 +119,10 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple
resolveHeaderViews();
addFeedbackOnClickListener(row);
addCloseButtonOnClickListener(row);
+
+ if (NotificationAddXOnHoverToDismiss.isEnabled()) {
+ mRow.addDismissButtonTargetStateListener(mHoverListener);
+ }
}
@Override
@@ -166,13 +174,34 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple
}
}
+ private ExpandableNotificationRow.DismissButtonTargetVisibilityListener mHoverListener = new
+ ExpandableNotificationRow.DismissButtonTargetVisibilityListener() {
+ @Override
+ public void onTargetVisibilityChanged(boolean targetVisible) {
+ NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode();
+
+ if (mCloseButton != null) {
+ mCloseButton.setVisibility(targetVisible ? VISIBLE : GONE);
+ }
+ }
+ };
+
+ @Override
+ public void setRemoved() {
+ super.setRemoved();
+
+ if (NotificationAddXOnHoverToDismiss.isEnabled()) {
+ mRow.removeDismissButtonTargetStateListener(mHoverListener);
+ }
+ }
+
/**
* Shows the given feedback icon, or hides the icon if null.
*/
@Override
public void setFeedbackIcon(@Nullable FeedbackIcon icon) {
if (mFeedbackIcon != null) {
- mFeedbackIcon.setVisibility(icon != null ? View.VISIBLE : View.GONE);
+ mFeedbackIcon.setVisibility(icon != null ? VISIBLE : GONE);
if (icon != null) {
if (mFeedbackIcon instanceof ImageButton) {
((ImageButton) mFeedbackIcon).setImageResource(icon.getIconRes());
@@ -266,7 +295,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple
boolean expandable,
View.OnClickListener onClickListener,
boolean requestLayout) {
- mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE);
+ mExpandButton.setVisibility(expandable ? VISIBLE : GONE);
mExpandButton.setOnClickListener(expandable ? onClickListener : null);
if (mAltExpandTarget != null) {
mAltExpandTarget.setOnClickListener(expandable ? onClickListener : null);
@@ -294,7 +323,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple
@Override
public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
if (mAudiblyAlertedIcon != null) {
- mAudiblyAlertedIcon.setVisibility(audiblyAlerted ? View.VISIBLE : View.GONE);
+ mAudiblyAlertedIcon.setVisibility(audiblyAlerted ? VISIBLE : GONE);
}
}
@@ -371,6 +400,7 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper imple
((DateTimeView) timeView).setTime(whenMillis);
}
}
+
protected void addTransformedViews(View... views) {
for (View view : views) {
if (view != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationAddXOnHoverToDismiss.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationAddXOnHoverToDismiss.kt
new file mode 100644
index 000000000000..0961874b2276
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationAddXOnHoverToDismiss.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.systemui.statusbar.notification.shared
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the notification dismiss button on hover flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object NotificationAddXOnHoverToDismiss {
+ const val FLAG_NAME = Flags.FLAG_NOTIFICATION_ADD_X_ON_HOVER_TO_DISMISS
+
+ val token: FlagToken
+ get() = FlagToken(FLAG_NAME, isEnabled)
+
+ @JvmStatic
+ inline val isEnabled
+ get() = Flags.notificationAddXOnHoverToDismiss()
+
+ @JvmStatic
+ inline fun isUnexpectedlyInLegacyMode() =
+ RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+ @JvmStatic
+ inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
index 5c9a0b939dc7..f85545ef95f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
@@ -100,6 +100,9 @@ public interface NotificationListContainer extends
*/
void addContainerViewAt(View v, int index);
+ /** Sets whether the notificatios are displayed on the unoccluded lockscreen. */
+ void setOnLockscreen(boolean isOnKeyguard);
+
/**
* Sets the maximum number of notifications to display.
*
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 57af8ea19722..bddf6dffe7c0 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
@@ -575,6 +575,7 @@ public class NotificationStackScrollLayout
@Nullable private SplitShadeStateController mSplitShadeStateController = null;
private boolean mIsSmallLandscapeLockscreenEnabled = false;
private boolean mSuppressHeightUpdates;
+ private boolean mIsOnLockscreen;
/** Pass splitShadeStateController to view and update split shade */
public void passSplitShadeStateController(SplitShadeStateController splitShadeStateController) {
@@ -3228,9 +3229,12 @@ public class NotificationStackScrollLayout
private void onViewAddedInternal(ExpandableView child) {
updateHideSensitiveForChild(child);
child.setOnHeightChangedListener(mOnChildHeightChangedListener);
- if (child instanceof ExpandableNotificationRow) {
+ if (child instanceof ExpandableNotificationRow row) {
NotificationEntry entry = ((ExpandableNotificationRow) child).getEntry();
entry.addOnSensitivityChangedListener(mOnChildSensitivityChangedListener);
+ if (SceneContainerFlag.isEnabled()) {
+ row.setOnKeyguard(mIsOnLockscreen);
+ }
}
generateAddAnimation(child, false /* fromMoreCard */);
updateAnimationState(child);
@@ -4752,8 +4756,11 @@ public class NotificationStackScrollLayout
}
}
- void goToFullShade(long delay) {
- SceneContainerFlag.assertInLegacyMode();
+ /**
+ * Requests an animation for the next stack height update, to animate from the constrained stack
+ * displayed on the lock screen, to the scrollable stack displayed in the expanded shade.
+ */
+ public void animateGoToFullShade(long delay) {
mGoToFullShadeNeedsAnimation = true;
mGoToFullShadeDelay = delay;
mNeedsAnimation = true;
@@ -5356,12 +5363,38 @@ public class NotificationStackScrollLayout
shelf.bind(mAmbientState, this, mController.getNotificationRoundnessManager());
}
+ /**
+ * Whether the notifications are displayed over the unoccluded lockscreen. Returns false on the
+ * locked shade.
+ */
+ public boolean isOnLockscreen() {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return false;
+ return mIsOnLockscreen;
+ }
+
+ /** @see #isOnLockscreen() */
+ public void setOnLockscreen(boolean isOnLockscreen) {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+ if (mIsOnLockscreen != isOnLockscreen) {
+ mIsOnLockscreen = isOnLockscreen;
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (child instanceof ExpandableNotificationRow childRow) {
+ childRow.setOnKeyguard(isOnLockscreen);
+ }
+ }
+ }
+ }
+
public void setMaxDisplayedNotifications(int maxDisplayedNotifications) {
if (mMaxDisplayedNotifications != maxDisplayedNotifications) {
mMaxDisplayedNotifications = maxDisplayedNotifications;
if (SceneContainerFlag.isEnabled()) {
updateIntrinsicStackHeight();
updateStackEndHeightAndStackHeight(mAmbientState.getExpansionFraction());
+ if (maxDisplayedNotifications == -1) {
+ animateGoToFullShade(0);
+ }
} else {
updateContentHeight();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index dc1a191ce233..3d7501deafc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -1222,7 +1222,7 @@ public class NotificationStackScrollLayoutController implements Dumpable {
public void goToFullShade(long delay) {
SceneContainerFlag.assertInLegacyMode();
- mView.goToFullShade(delay);
+ mView.animateGoToFullShade(delay);
}
public void setOverScrollAmount(float amount, boolean onTop, boolean animate,
@@ -1603,6 +1603,12 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
}
+ /** Sets whether the NSSL is displayed over the unoccluded Lockscreen. */
+ public void setOnLockscreen(boolean isOnLockscreen) {
+ if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+ mNotificationListContainer.setOnLockscreen(isOnLockscreen);
+ }
+
/**
* Set the maximum number of notifications that can currently be displayed
*/
@@ -2029,6 +2035,11 @@ public class NotificationStackScrollLayoutController implements Dumpable {
}
@Override
+ public void setOnLockscreen(boolean isOnLockscreen) {
+ mView.setOnLockscreen(isOnLockscreen);
+ }
+
+ @Override
public void setMaxDisplayedNotifications(int maxNotifications) {
mView.setMaxDisplayedNotifications(maxNotifications);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 4a55dfaaf7ea..ea714608ea66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -118,8 +118,12 @@ constructor(
}
launch {
- viewModel.getMaxNotifications(calculateMaxNotifications).collect {
- controller.setMaxDisplayedNotifications(it)
+ viewModel.getLockscreenDisplayConfig(calculateMaxNotifications).collect {
+ (isOnLockscreen, maxNotifications) ->
+ if (SceneContainerFlag.isEnabled) {
+ controller.setOnLockscreen(isOnLockscreen)
+ }
+ controller.setMaxDisplayedNotifications(maxNotifications)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index fb60f266e188..a55a165d9b66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -718,9 +718,11 @@ constructor(
* When expanding or when the user is interacting with the shade, keep the count stable; do not
* emit a value.
*/
- fun getMaxNotifications(calculateSpace: (Float, Boolean) -> Int): Flow<Int> {
+ fun getLockscreenDisplayConfig(
+ calculateSpace: (Float, Boolean) -> Int
+ ): Flow<LockscreenDisplayConfig> {
val showLimitedNotifications = isOnLockscreenWithoutShade
- val showUnlimitedNotifications =
+ val showUnlimitedNotificationsAndIsOnLockScreen =
combine(
isOnLockscreen,
keyguardInteractor.statusBarState,
@@ -730,28 +732,42 @@ constructor(
)
.onStart { emit(false) },
) { isOnLockscreen, statusBarState, showAllNotifications ->
- statusBarState == SHADE_LOCKED || !isOnLockscreen || showAllNotifications
+ (statusBarState == SHADE_LOCKED || !isOnLockscreen || showAllNotifications) to
+ isOnLockscreen
}
+ @Suppress("UNCHECKED_CAST")
return combineTransform(
showLimitedNotifications,
- showUnlimitedNotifications,
+ showUnlimitedNotificationsAndIsOnLockScreen,
shadeInteractor.isUserInteracting,
availableHeight,
interactor.notificationStackChanged,
interactor.useExtraShelfSpace,
) { flows ->
val showLimitedNotifications = flows[0] as Boolean
- val showUnlimitedNotifications = flows[1] as Boolean
+ val (showUnlimitedNotifications, isOnLockscreen) =
+ flows[1] as Pair<Boolean, Boolean>
val isUserInteracting = flows[2] as Boolean
val availableHeight = flows[3] as Float
val useExtraShelfSpace = flows[5] as Boolean
if (!isUserInteracting) {
if (showLimitedNotifications) {
- emit(calculateSpace(availableHeight, useExtraShelfSpace))
+ emit(
+ LockscreenDisplayConfig(
+ isOnLockscreen = isOnLockscreen,
+ maxNotifications =
+ calculateSpace(availableHeight, useExtraShelfSpace),
+ )
+ )
} else if (showUnlimitedNotifications) {
- emit(-1)
+ emit(
+ LockscreenDisplayConfig(
+ isOnLockscreen = isOnLockscreen,
+ maxNotifications = -1,
+ )
+ )
}
}
}
@@ -775,9 +791,9 @@ constructor(
SceneContainerFlag.assertInLegacyMode()
return combine(
- getMaxNotifications(calculateMaxNotifications).map {
- val height = calculateHeight(it)
- if (it == 0) {
+ getLockscreenDisplayConfig(calculateMaxNotifications).map { (_, maxNotifications) ->
+ val height = calculateHeight(maxNotifications)
+ if (maxNotifications == 0) {
height - shelfHeight
} else {
height
@@ -815,4 +831,13 @@ constructor(
*/
data class FloatAtEnd(val width: Int) : HorizontalPosition
}
+
+ /**
+ * Data class representing a configuration for displaying Notifications on the Lockscreen.
+ *
+ * @param isOnLockscreen is the user on the lockscreen
+ * @param maxNotifications Limit for the max number of top-level Notifications to be displayed.
+ * A value of -1 indicates no limit.
+ */
+ data class LockscreenDisplayConfig(val isOnLockscreen: Boolean, val maxNotifications: Int)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.kt
new file mode 100644
index 000000000000..636e1c45bc81
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import android.content.Context
+import android.view.MotionEvent
+import com.android.systemui.statusbar.AutoHideUiElement
+import java.io.PrintWriter
+
+/**
+ * Controls the auto-hide behavior of system bars (status bar, navigation bar).
+ *
+ * This interface provides methods to manage the auto-hide schedule of system bars, allowing them to
+ * be shown or hidden.
+ */
+interface AutoHideController {
+ /**
+ * Sets a [AutoHideUiElement] status bar that should be controlled by the [AutoHideController].
+ */
+ fun setStatusBar(element: AutoHideUiElement)
+
+ /**
+ * Sets a [AutoHideUiElement] navigation bar that should be controlled by the
+ * [AutoHideController].
+ */
+ fun setNavigationBar(element: AutoHideUiElement)
+
+ /** Resumes the auto-hide behavior that was previously suspended. */
+ fun resumeSuspendedAutoHide()
+
+ /** Suspends the auto-hide behavior. */
+ fun suspendAutoHide()
+
+ /** Schedules or cancels auto hide behavior based on current system bar state. */
+ fun touchAutoHide()
+
+ /** Hides system bars on user touch if the interaction requires them to be hidden. */
+ fun checkUserAutoHide(event: MotionEvent)
+
+ /** Called when work should stop and resources should be released. */
+ fun stop()
+
+ /** Dumps the current state of the [AutoHideController] */
+ fun dump(pw: PrintWriter)
+
+ /** Injectable factory for creating a [AutoHideController]. */
+ interface Factory {
+ /** Create an [AutoHideController] */
+ fun create(context: Context): AutoHideController
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerImpl.java
index 1358cfd3e8da..4fbfbb254064 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,6 @@ import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull;
-import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.AutoHideUiElement;
@@ -36,9 +35,7 @@ import java.io.PrintWriter;
import javax.inject.Inject;
-/** A controller to control all auto-hide things. Also see {@link AutoHideUiElement}. */
-@SysUISingleton
-public class AutoHideController {
+public class AutoHideControllerImpl implements AutoHideController {
private static final String TAG = "AutoHideController";
private static final int AUTO_HIDE_TIMEOUT_MS = 2250;
private static final int USER_AUTO_HIDE_TIMEOUT_MS = 350;
@@ -61,7 +58,7 @@ public class AutoHideController {
};
@Inject
- public AutoHideController(Context context,
+ public AutoHideControllerImpl(Context context,
@Main Handler handler,
IWindowManager iWindowManager) {
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
@@ -70,18 +67,12 @@ public class AutoHideController {
mDisplayId = context.getDisplayId();
}
- /**
- * Sets a {@link AutoHideUiElement} status bar that should be controlled by the
- * {@link AutoHideController}.
- */
+ @Override
public void setStatusBar(AutoHideUiElement element) {
mStatusBar = element;
}
- /**
- * Sets a {@link AutoHideUiElement} navigation bar that should be controlled by the
- * {@link AutoHideController}.
- */
+ @Override
public void setNavigationBar(AutoHideUiElement element) {
mNavigationBar = element;
}
@@ -102,6 +93,7 @@ public class AutoHideController {
}
}
+ @Override
public void resumeSuspendedAutoHide() {
if (mAutoHideSuspended) {
scheduleAutoHide();
@@ -112,6 +104,7 @@ public class AutoHideController {
}
}
+ @Override
public void suspendAutoHide() {
mHandler.removeCallbacks(mAutoHide);
Runnable checkBarModesRunnable = getCheckBarModesRunnable();
@@ -121,7 +114,7 @@ public class AutoHideController {
mAutoHideSuspended = isAnyTransientBarShown();
}
- /** Schedules or cancels auto hide behavior based on current system bar state. */
+ @Override
public void touchAutoHide() {
// update transient bar auto hide
if (isAnyTransientBarShown()) {
@@ -156,6 +149,7 @@ public class AutoHideController {
FLAG_CONTENT_CONTROLS);
}
+ @Override
public void checkUserAutoHide(MotionEvent event) {
boolean shouldHide = isAnyTransientBarShown()
&& event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar.
@@ -196,6 +190,12 @@ public class AutoHideController {
return false;
}
+ @Override
+ public void stop() {
+ mHandler.removeCallbacks(mAutoHide);
+ }
+
+ @Override
public void dump(@NonNull PrintWriter pw) {
pw.println("AutoHideController:");
pw.println("\tmAutoHideSuspended=" + mAutoHideSuspended);
@@ -205,10 +205,7 @@ public class AutoHideController {
pw.println("\tgetUserAutoHideTimeout=" + getUserAutoHideTimeout());
}
- /**
- * Injectable factory for creating a {@link AutoHideController}.
- */
- public static class Factory {
+ public static class Factory implements AutoHideController.Factory {
private final Handler mHandler;
private final IWindowManager mIWindowManager;
@@ -219,8 +216,9 @@ public class AutoHideController {
}
/** Create an {@link AutoHideController} */
+ @Override
public AutoHideController create(Context context) {
- return new AutoHideController(context, mHandler, mIWindowManager);
+ return new AutoHideControllerImpl(context, mHandler, mIWindowManager);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
new file mode 100644
index 000000000000..744f96918eef
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideControllerStore.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.display.data.repository.DisplayRepository
+import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
+import com.android.systemui.display.data.repository.PerDisplayStore
+import com.android.systemui.display.data.repository.PerDisplayStoreImpl
+import com.android.systemui.display.data.repository.SingleDisplayStore
+import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/** Provides per display instances of [AutoHideController] */
+interface AutoHideControllerStore : PerDisplayStore<AutoHideController>
+
+@SysUISingleton
+class MultiDisplayAutoHideControllerStore
+@Inject
+constructor(
+ @Background backgroundApplicationScope: CoroutineScope,
+ displayRepository: DisplayRepository,
+ private val displayWindowPropertiesRepository: DisplayWindowPropertiesRepository,
+ private val autoHideControllerFactory: AutoHideControllerImpl.Factory,
+) :
+ AutoHideControllerStore,
+ PerDisplayStoreImpl<AutoHideController>(backgroundApplicationScope, displayRepository) {
+
+ init {
+ StatusBarConnectedDisplays.assertInNewMode()
+ }
+
+ override fun createInstanceForDisplay(displayId: Int): AutoHideController {
+ val displayWindowProperties =
+ displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR)
+ return autoHideControllerFactory.create(displayWindowProperties.context)
+ }
+
+ override suspend fun onDisplayRemovalAction(instance: AutoHideController) {
+ instance.stop()
+ }
+
+ override val instanceClass = AutoHideController::class.java
+}
+
+@SysUISingleton
+class SingleDisplayAutoHideControllerStore
+@Inject
+constructor(defaultController: AutoHideController) :
+ AutoHideControllerStore,
+ PerDisplayStore<AutoHideController> by SingleDisplayStore(defaultController) {
+
+ init {
+ StatusBarConnectedDisplays.assertInLegacyMode()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
index 58386b0cad7c..ee8c1ae6c5f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.kt
@@ -35,7 +35,12 @@ import com.android.systemui.statusbar.data.repository.PrivacyDotViewControllerSt
import com.android.systemui.statusbar.data.repository.PrivacyDotWindowControllerStoreModule
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
import com.android.systemui.statusbar.events.PrivacyDotViewControllerModule
+import com.android.systemui.statusbar.phone.AutoHideController
+import com.android.systemui.statusbar.phone.AutoHideControllerImpl
+import com.android.systemui.statusbar.phone.AutoHideControllerStore
import com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks
+import com.android.systemui.statusbar.phone.MultiDisplayAutoHideControllerStore
+import com.android.systemui.statusbar.phone.SingleDisplayAutoHideControllerStore
import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
import com.android.systemui.statusbar.window.data.repository.StatusBarWindowStateRepositoryStore
import com.android.systemui.statusbar.window.data.repository.StatusBarWindowStateRepositoryStoreImpl
@@ -75,6 +80,9 @@ interface StatusBarPhoneModule {
@Binds fun statusBarInitializer(@Default impl: StatusBarInitializerImpl): StatusBarInitializer
+ @Binds
+ fun autoHideControllerFactory(impl: AutoHideControllerImpl.Factory): AutoHideController.Factory
+
companion object {
/** Binds {@link StatusBarInitializer} as a {@link CoreStartable}. */
@Provides
@@ -186,5 +194,18 @@ interface StatusBarPhoneModule {
singleDisplayStoreLazy.get()
}
}
+
+ @Provides
+ @SysUISingleton
+ fun autoHideStore(
+ singleDisplayLazy: Lazy<SingleDisplayAutoHideControllerStore>,
+ multiDisplayLazy: Lazy<MultiDisplayAutoHideControllerStore>,
+ ): AutoHideControllerStore {
+ return if (StatusBarConnectedDisplays.isEnabled) {
+ multiDisplayLazy.get()
+ } else {
+ singleDisplayLazy.get()
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index a115baad257d..52f80fbf50fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -24,6 +24,7 @@ import android.media.MediaRouter;
import android.media.MediaRouter.RouteInfo;
import android.media.projection.MediaProjectionInfo;
import android.media.projection.MediaProjectionManager;
+import android.media.projection.StopReason;
import android.os.Handler;
import android.util.ArrayMap;
@@ -190,7 +191,7 @@ public class CastControllerImpl implements CastController {
if (isProjection) {
final MediaProjectionInfo projection = (MediaProjectionInfo) device.getTag();
if (Objects.equals(mProjectionManager.getActiveProjectionInfo(), projection)) {
- mProjectionManager.stopActiveProjection();
+ mProjectionManager.stopActiveProjection(StopReason.STOP_QS_TILE);
} else {
mLogger.logStopCastingNoProjection(projection);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
index 425aad2bd43c..4aaa82e4a16d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
@@ -404,7 +404,7 @@ class ActivityTransitionAnimatorTest : SysuiTestCase() {
@Test
fun creatingRunnerWithLazyInitializationThrows_whenTheFlagsAreDisabled() {
assertThrows(IllegalStateException::class.java) {
- activityTransitionAnimator.createRunner(controller, initializeLazily = true)
+ activityTransitionAnimator.createRunner(controller, longLived = true)
}
}
@@ -414,7 +414,7 @@ class ActivityTransitionAnimatorTest : SysuiTestCase() {
)
@Test
fun runnerCreatesDelegateLazily_whenPostingTimeouts() {
- val runner = activityTransitionAnimator.createRunner(controller, initializeLazily = true)
+ val runner = activityTransitionAnimator.createRunner(controller, longLived = true)
assertNull(runner.delegate)
runner.postTimeouts()
assertNotNull(runner.delegate)
@@ -426,7 +426,7 @@ class ActivityTransitionAnimatorTest : SysuiTestCase() {
)
@Test
fun runnerCreatesDelegateLazily_onAnimationStart() {
- val runner = activityTransitionAnimator.createRunner(controller, initializeLazily = true)
+ val runner = activityTransitionAnimator.createRunner(controller, longLived = true)
assertNull(runner.delegate)
// The delegate is cleaned up after execution (which happens in another thread), so what we
@@ -458,7 +458,7 @@ class ActivityTransitionAnimatorTest : SysuiTestCase() {
)
@Test
fun runnerCreatesDelegateLazily_onAnimationTakeover() {
- val runner = activityTransitionAnimator.createRunner(controller, initializeLazily = true)
+ val runner = activityTransitionAnimator.createRunner(controller, longLived = true)
assertNull(runner.delegate)
// The delegate is cleaned up after execution (which happens in another thread), so what we
@@ -489,7 +489,7 @@ class ActivityTransitionAnimatorTest : SysuiTestCase() {
)
@Test
fun animationTakeoverThrows_whenTheFlagsAreDisabled() {
- val runner = activityTransitionAnimator.createRunner(controller, initializeLazily = false)
+ val runner = activityTransitionAnimator.createRunner(controller, longLived = false)
assertThrows(IllegalStateException::class.java) {
runner.takeOverAnimation(
arrayOf(fakeWindow()),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
index 2c1718176571..bfbdc50c32b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
@@ -24,9 +24,9 @@ import android.os.Handler
import android.os.Looper
import android.os.PatternMatcher
import android.os.UserHandle
-import androidx.test.filters.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
import com.android.systemui.dump.DumpManager
@@ -40,8 +40,9 @@ import java.util.concurrent.Executor
import junit.framework.Assert.assertSame
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.advanceUntilIdle
-import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -68,39 +69,28 @@ class BroadcastDispatcherTest : SysuiTestCase() {
val DEFAULT_PERMISSION: String? = null
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
+
const val TEST_ACTION = "TEST_ACTION"
const val TEST_SCHEME = "TEST_SCHEME"
const val TEST_PATH = "TEST_PATH"
const val TEST_TYPE = "test/type"
}
- @Mock
- private lateinit var mockContext: Context
- @Mock
- private lateinit var mockUBRUser0: UserBroadcastDispatcher
- @Mock
- private lateinit var mockUBRUser1: UserBroadcastDispatcher
- @Mock
- private lateinit var broadcastReceiver: BroadcastReceiver
- @Mock
- private lateinit var broadcastReceiverOther: BroadcastReceiver
- @Mock
- private lateinit var intentFilter: IntentFilter
- @Mock
- private lateinit var intentFilterOther: IntentFilter
- @Mock
- private lateinit var mockHandler: Handler
- @Mock
- private lateinit var logger: BroadcastDispatcherLogger
- @Mock
- private lateinit var userTracker: UserTracker
- @Mock
- private lateinit var removalPendingStore: PendingRemovalStore
+ @Mock private lateinit var mockContext: Context
+ @Mock private lateinit var mockUBRUser0: UserBroadcastDispatcher
+ @Mock private lateinit var mockUBRUser1: UserBroadcastDispatcher
+ @Mock private lateinit var broadcastReceiver: BroadcastReceiver
+ @Mock private lateinit var broadcastReceiverOther: BroadcastReceiver
+ @Mock private lateinit var intentFilter: IntentFilter
+ @Mock private lateinit var intentFilterOther: IntentFilter
+ @Mock private lateinit var mockHandler: Handler
+ @Mock private lateinit var logger: BroadcastDispatcherLogger
+ @Mock private lateinit var userTracker: UserTracker
+ @Mock private lateinit var removalPendingStore: PendingRemovalStore
private lateinit var mainExecutor: Executor
- @Captor
- private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData>
+ @Captor private lateinit var argumentCaptor: ArgumentCaptor<ReceiverData>
private lateinit var testableLooper: TestableLooper
private lateinit var broadcastDispatcher: BroadcastDispatcher
@@ -112,7 +102,8 @@ class BroadcastDispatcherTest : SysuiTestCase() {
mainExecutor = FakeExecutor(FakeSystemClock())
`when`(mockContext.mainExecutor).thenReturn(mainExecutor)
- broadcastDispatcher = TestBroadcastDispatcher(
+ broadcastDispatcher =
+ TestBroadcastDispatcher(
mockContext,
mainExecutor,
testableLooper.looper,
@@ -121,7 +112,8 @@ class BroadcastDispatcherTest : SysuiTestCase() {
logger,
userTracker,
removalPendingStore,
- mapOf(0 to mockUBRUser0, 1 to mockUBRUser1))
+ mapOf(0 to mockUBRUser0, 1 to mockUBRUser1),
+ )
// These should be valid filters
`when`(intentFilter.countActions()).thenReturn(1)
@@ -131,10 +123,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testAddingReceiverToCorrectUBR() {
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, user0)
broadcastDispatcher.registerReceiverWithHandler(
- broadcastReceiverOther, intentFilterOther, mockHandler, user1)
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ user0,
+ )
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiverOther,
+ intentFilterOther,
+ mockHandler,
+ user1,
+ )
testableLooper.processAllMessages()
@@ -152,7 +152,11 @@ class BroadcastDispatcherTest : SysuiTestCase() {
fun testAddingReceiverToCorrectUBR_executor() {
broadcastDispatcher.registerReceiver(broadcastReceiver, intentFilter, mainExecutor, user0)
broadcastDispatcher.registerReceiver(
- broadcastReceiverOther, intentFilterOther, mainExecutor, user1)
+ broadcastReceiverOther,
+ intentFilterOther,
+ mainExecutor,
+ user1,
+ )
testableLooper.processAllMessages()
@@ -169,7 +173,10 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testAddReceiverDefaultFlag_handler() {
broadcastDispatcher.registerReceiverWithHandler(
- broadcastReceiver, intentFilter, mockHandler)
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ )
testableLooper.processAllMessages()
verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG))
@@ -183,7 +190,11 @@ class BroadcastDispatcherTest : SysuiTestCase() {
val flag = 3
broadcastDispatcher.registerReceiverWithHandler(
- broadcastReceiver, intentFilter, mockHandler, flags = flag)
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ flags = flag,
+ )
testableLooper.processAllMessages()
verify(mockUBRUser0).registerReceiver(capture(argumentCaptor), eq(flag))
@@ -212,7 +223,7 @@ class BroadcastDispatcherTest : SysuiTestCase() {
broadcastReceiver,
intentFilter,
flags = flag,
- permission = permission
+ permission = permission,
)
testableLooper.processAllMessages()
@@ -250,10 +261,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testRemovingReceiversRemovesFromAllUBR() {
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, user0)
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, user1)
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ user0,
+ )
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ user1,
+ )
broadcastDispatcher.unregisterReceiver(broadcastReceiver)
@@ -265,10 +284,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test
fun testRemoveReceiverFromUser() {
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, user0)
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, user1)
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ user0,
+ )
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ user1,
+ )
broadcastDispatcher.unregisterReceiverForUser(broadcastReceiver, user0)
@@ -282,13 +309,17 @@ class BroadcastDispatcherTest : SysuiTestCase() {
fun testRegisterCurrentAsActualUser() {
`when`(userTracker.userId).thenReturn(user1.identifier)
- broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter,
- mockHandler, UserHandle.CURRENT)
+ broadcastDispatcher.registerReceiverWithHandler(
+ broadcastReceiver,
+ intentFilter,
+ mockHandler,
+ UserHandle.CURRENT,
+ )
testableLooper.processAllMessages()
- verify(mockUBRUser1).registerReceiver(
- capture(argumentCaptor), eq(Context.RECEIVER_EXPORTED))
+ verify(mockUBRUser1)
+ .registerReceiver(capture(argumentCaptor), eq(Context.RECEIVER_EXPORTED))
assertSame(broadcastReceiver, argumentCaptor.value.receiver)
}
@@ -300,41 +331,38 @@ class BroadcastDispatcherTest : SysuiTestCase() {
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataScheme() {
- val testFilter = IntentFilter(TEST_ACTION).apply {
- addDataScheme(TEST_SCHEME)
- }
+ val testFilter = IntentFilter(TEST_ACTION).apply { addDataScheme(TEST_SCHEME) }
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataAuthority() {
- val testFilter = IntentFilter(TEST_ACTION).apply {
- addDataAuthority(mock(IntentFilter.AuthorityEntry::class.java))
- }
+ val testFilter =
+ IntentFilter(TEST_ACTION).apply {
+ addDataAuthority(mock(IntentFilter.AuthorityEntry::class.java))
+ }
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataPath() {
- val testFilter = IntentFilter(TEST_ACTION).apply {
- addDataPath(TEST_PATH, PatternMatcher.PATTERN_LITERAL)
- }
+ val testFilter =
+ IntentFilter(TEST_ACTION).apply {
+ addDataPath(TEST_PATH, PatternMatcher.PATTERN_LITERAL)
+ }
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotContainDataType() {
- val testFilter = IntentFilter(TEST_ACTION).apply {
- addDataType(TEST_TYPE)
- }
+ val testFilter = IntentFilter(TEST_ACTION).apply { addDataType(TEST_TYPE) }
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@Test(expected = IllegalArgumentException::class)
fun testFilterMustNotSetPriority() {
- val testFilter = IntentFilter(TEST_ACTION).apply {
- priority = IntentFilter.SYSTEM_HIGH_PRIORITY
- }
+ val testFilter =
+ IntentFilter(TEST_ACTION).apply { priority = IntentFilter.SYSTEM_HIGH_PRIORITY }
broadcastDispatcher.registerReceiver(broadcastReceiver, testFilter)
}
@@ -366,12 +394,14 @@ class BroadcastDispatcherTest : SysuiTestCase() {
val inOrderUser0 = inOrder(mockUBRUser0, removalPendingStore)
inOrderUser0.verify(mockUBRUser0).unregisterReceiver(broadcastReceiver)
- inOrderUser0.verify(removalPendingStore)
+ inOrderUser0
+ .verify(removalPendingStore)
.clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL)
val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore)
inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
- inOrderUser1.verify(removalPendingStore)
+ inOrderUser1
+ .verify(removalPendingStore)
.clearPendingRemoval(broadcastReceiver, UserHandle.USER_ALL)
}
@@ -385,21 +415,21 @@ class BroadcastDispatcherTest : SysuiTestCase() {
val inOrderUser1 = inOrder(mockUBRUser1, removalPendingStore)
inOrderUser1.verify(mockUBRUser1).unregisterReceiver(broadcastReceiver)
- inOrderUser1.verify(removalPendingStore)
+ inOrderUser1
+ .verify(removalPendingStore)
.clearPendingRemoval(broadcastReceiver, user1.identifier)
}
@Test
- fun testBroadcastFlow() = runBlockingTest {
- val flow = broadcastDispatcher.broadcastFlow(intentFilter, user1) { intent, receiver ->
- intent to receiver
- }
+ fun testBroadcastFlow() = runTest(UnconfinedTestDispatcher()) {
+ val flow =
+ broadcastDispatcher.broadcastFlow(intentFilter, user1) { intent, receiver ->
+ intent to receiver
+ }
// Collect the values into collectedValues.
val collectedValues = mutableListOf<Pair<Intent, BroadcastReceiver>>()
- val job = launch {
- flow.collect { collectedValues.add(it) }
- }
+ val job = launch { flow.collect { collectedValues.add(it) } }
testableLooper.processAllMessages()
verify(mockUBRUser1).registerReceiver(capture(argumentCaptor), eq(DEFAULT_FLAG))
@@ -436,17 +466,18 @@ class BroadcastDispatcherTest : SysuiTestCase() {
logger: BroadcastDispatcherLogger,
userTracker: UserTracker,
removalPendingStore: PendingRemovalStore,
- var mockUBRMap: Map<Int, UserBroadcastDispatcher>
- ) : BroadcastDispatcher(
- context,
- mainExecutor,
- backgroundRunningLooper,
- backgroundRunningExecutor,
- dumpManager,
- logger,
- userTracker,
- removalPendingStore
- ) {
+ var mockUBRMap: Map<Int, UserBroadcastDispatcher>,
+ ) :
+ BroadcastDispatcher(
+ context,
+ mainExecutor,
+ backgroundRunningLooper,
+ backgroundRunningExecutor,
+ dumpManager,
+ logger,
+ userTracker,
+ removalPendingStore,
+ ) {
override fun createUBRForUser(userId: Int): UserBroadcastDispatcher {
return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java))
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
index f706cf6980e1..d0ce34c2d68d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
@@ -23,18 +23,20 @@ import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_OTH
import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_RESERVED_GESTURE
import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS
import android.hardware.input.fakeInputManager
-import android.os.SystemClock
-import android.view.KeyEvent.ACTION_DOWN
-import android.view.KeyEvent.KEYCODE_A
-import android.view.KeyEvent.META_CTRL_ON
-import android.view.KeyEvent.META_META_ON
-import androidx.compose.ui.input.key.KeyEvent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allAppsInputGestureData
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedStandardAddShortcutUiState
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedStandardDeleteShortcutUiState
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.goHomeInputGestureData
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.keyDownEventWithActionKeyPressed
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.keyDownEventWithoutActionKeyPressed
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.keyUpEventWithActionKeyPressed
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardAddCustomShortcutRequestInfo
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardAddShortcutRequest
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardDeleteCustomShortcutRequestInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shortcutCustomizationViewModelFactory
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
@@ -97,7 +99,7 @@ class ShortcutCustomizationViewModelTest : SysuiTestCase() {
@Test
fun uiState_correctlyUpdatedWhenDeleteShortcutCustomizationIsRequested() {
testScope.runTest {
- viewModel.onShortcutCustomizationRequested(standardDeleteShortcutRequest)
+ viewModel.onShortcutCustomizationRequested(standardDeleteCustomShortcutRequestInfo)
val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
assertThat(uiState).isEqualTo(expectedStandardDeleteShortcutUiState)
@@ -120,7 +122,7 @@ class ShortcutCustomizationViewModelTest : SysuiTestCase() {
fun uiState_consumedOnDeleteDialogShown() {
testScope.runTest {
val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
- viewModel.onShortcutCustomizationRequested(standardDeleteShortcutRequest)
+ viewModel.onShortcutCustomizationRequested(standardDeleteCustomShortcutRequestInfo)
viewModel.onDialogShown()
assertThat(
@@ -168,7 +170,7 @@ class ShortcutCustomizationViewModelTest : SysuiTestCase() {
fun uiState_errorMessage_isEmptyByDefault() {
testScope.runTest {
val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
- viewModel.onShortcutCustomizationRequested(allAppsShortcutCustomizationRequest)
+ viewModel.onShortcutCustomizationRequested(standardAddCustomShortcutRequestInfo)
viewModel.onDialogShown()
assertThat((uiState as ShortcutCustomizationUiState.AddShortcutDialog).errorMessage)
@@ -227,6 +229,21 @@ class ShortcutCustomizationViewModelTest : SysuiTestCase() {
}
@Test
+ fun uiState_becomesInactiveAfterSuccessfullyDeletingShortcut() {
+ testScope.runTest {
+ val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
+ whenever(inputManager.getCustomInputGestures(any()))
+ .thenReturn(listOf(goHomeInputGestureData, allAppsInputGestureData))
+ whenever(inputManager.removeCustomInputGesture(any()))
+ .thenReturn(CUSTOM_INPUT_GESTURE_RESULT_SUCCESS)
+
+ openDeleteShortcutDialogAndDeleteShortcut()
+
+ assertThat(uiState).isEqualTo(ShortcutCustomizationUiState.Inactive)
+ }
+ }
+
+ @Test
fun onKeyPressed_handlesKeyEvents_whereActionKeyIsAlsoPressed() {
testScope.runTest {
viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
@@ -281,7 +298,7 @@ class ShortcutCustomizationViewModelTest : SysuiTestCase() {
}
private suspend fun openAddShortcutDialogAndSetShortcut() {
- viewModel.onShortcutCustomizationRequested(allAppsShortcutCustomizationRequest)
+ viewModel.onShortcutCustomizationRequested(standardAddCustomShortcutRequestInfo)
viewModel.onDialogShown()
viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
@@ -290,71 +307,10 @@ class ShortcutCustomizationViewModelTest : SysuiTestCase() {
viewModel.onSetShortcut()
}
- private val keyDownEventWithoutActionKeyPressed =
- KeyEvent(
- android.view.KeyEvent(
- /* downTime = */ SystemClock.uptimeMillis(),
- /* eventTime = */ SystemClock.uptimeMillis(),
- /* action = */ ACTION_DOWN,
- /* code = */ KEYCODE_A,
- /* repeat = */ 0,
- /* metaState = */ META_CTRL_ON,
- )
- )
-
- private val keyDownEventWithActionKeyPressed =
- KeyEvent(
- android.view.KeyEvent(
- /* downTime = */ SystemClock.uptimeMillis(),
- /* eventTime = */ SystemClock.uptimeMillis(),
- /* action = */ ACTION_DOWN,
- /* code = */ KEYCODE_A,
- /* repeat = */ 0,
- /* metaState = */ META_CTRL_ON or META_META_ON,
- )
- )
-
- private val keyUpEventWithActionKeyPressed =
- KeyEvent(
- android.view.KeyEvent(
- /* downTime = */ SystemClock.uptimeMillis(),
- /* eventTime = */ SystemClock.uptimeMillis(),
- /* action = */ ACTION_DOWN,
- /* code = */ KEYCODE_A,
- /* repeat = */ 0,
- /* metaState = */ 0,
- )
- )
-
- private val standardAddShortcutRequest =
- ShortcutCustomizationRequestInfo.Add(
- label = "Standard shortcut",
- categoryType = ShortcutCategoryType.System,
- subCategoryLabel = "Standard subcategory",
- )
-
- private val standardDeleteShortcutRequest =
- ShortcutCustomizationRequestInfo.Delete(
- label = "Standard shortcut",
- categoryType = ShortcutCategoryType.System,
- subCategoryLabel = "Standard subcategory",
- )
-
- private val allAppsShortcutCustomizationRequest =
- ShortcutCustomizationRequestInfo.Add(
- label = "Open apps list",
- categoryType = ShortcutCategoryType.System,
- subCategoryLabel = "System controls",
- )
-
- private val expectedStandardAddShortcutUiState =
- ShortcutCustomizationUiState.AddShortcutDialog(
- shortcutLabel = "Standard shortcut",
- defaultCustomShortcutModifierKey =
- ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta),
- isDialogShowing = false,
- )
-
- private val expectedStandardDeleteShortcutUiState =
- ShortcutCustomizationUiState.DeleteShortcutDialog(isDialogShowing = false)
+ private suspend fun openDeleteShortcutDialogAndDeleteShortcut() {
+ viewModel.onShortcutCustomizationRequested(standardDeleteCustomShortcutRequestInfo)
+ viewModel.onDialogShown()
+
+ viewModel.deleteShortcutCurrentlyBeingCustomized()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
index bf4ef509ac80..eb1b44b75247 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaSwitchingControllerTest.java
@@ -59,6 +59,7 @@ import android.os.Bundle;
import android.os.PowerExemptionManager;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.service.notification.StatusBarNotification;
import android.testing.TestableLooper;
@@ -242,10 +243,14 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
mLocalMediaManager = spy(mMediaSwitchingController.mLocalMediaManager);
when(mLocalMediaManager.isPreferenceRouteListingExist()).thenReturn(false);
mMediaSwitchingController.mLocalMediaManager = mLocalMediaManager;
+
mMediaSwitchingController.mInputRouteManager =
new InputRouteManager(mContext, mAudioManager);
mInputRouteManager = spy(mMediaSwitchingController.mInputRouteManager);
mMediaSwitchingController.mInputRouteManager = mInputRouteManager;
+ when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS))
+ .thenReturn(new AudioDeviceInfo[0]);
+
MediaDescription.Builder builder = new MediaDescription.Builder();
builder.setTitle(TEST_SONG);
builder.setSubtitle(TEST_ARTIST);
@@ -483,11 +488,11 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
verify(mMediaDevice2, never()).setRangeZone(anyInt());
}
+ @DisableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
@Test
public void onDeviceListUpdate_verifyDeviceListCallback() {
// This test relies on mMediaSwitchingController.start being called while the selected
- // device
- // list has exactly one item, and that item's id is:
+ // device list has exactly one item, and that item's id is:
// - Different from both ids in mMediaDevices.
// - Different from the id of the route published by the device under test (usually the
// built-in speakers).
@@ -511,16 +516,54 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
assertThat(devices.containsAll(mMediaDevices)).isTrue();
assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+ // There should be 2 non-MediaDevice items: the "Speakers & Display" title, and the "Connect
+ // a device" button.
assertThat(mMediaSwitchingController.getMediaItemList().size())
.isEqualTo(mMediaDevices.size() + 2);
verify(mCb).onDeviceListChanged();
}
+ @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+ @Test
+ public void onDeviceListUpdate_verifyDeviceListCallback_inputRouting() {
+ // This test relies on mMediaSwitchingController.start being called while the selected
+ // device list has exactly one item, and that item's id is:
+ // - Different from both ids in mMediaDevices.
+ // - Different from the id of the route published by the device under test (usually the
+ // built-in speakers).
+ // So mock the selected device to respect these two preconditions.
+ MediaDevice mockSelectedMediaDevice = Mockito.mock(MediaDevice.class);
+ when(mockSelectedMediaDevice.getId()).thenReturn(TEST_DEVICE_3_ID);
+ doReturn(List.of(mockSelectedMediaDevice))
+ .when(mLocalMediaManager)
+ .getSelectedMediaDevice();
+
+ mMediaSwitchingController.start(mCb);
+ reset(mCb);
+
+ mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);
+ final List<MediaDevice> devices = new ArrayList<>();
+ for (MediaItem item : mMediaSwitchingController.getMediaItemList()) {
+ if (item.getMediaDevice().isPresent()) {
+ devices.add(item.getMediaDevice().get());
+ }
+ }
+
+ assertThat(devices.containsAll(mMediaDevices)).isTrue();
+ assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+ // When input routing is enabled, there should be 4 non-MediaDevice items: one for
+ // the "Output" title, one for the "Speakers & Displays" title, one for the "Connect a
+ // device" button, and one for the "Input" title.
+ assertThat(mMediaSwitchingController.getMediaItemList().size())
+ .isEqualTo(mMediaDevices.size() + 4);
+ verify(mCb).onDeviceListChanged();
+ }
+
+ @DisableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
@Test
public void advanced_onDeviceListUpdateWithConnectedDeviceRemote_verifyItemSize() {
// This test relies on mMediaSwitchingController.start being called while the selected
- // device
- // list has exactly one item, and that item's id is:
+ // device list has exactly one item, and that item's id is:
// - Different from both ids in mMediaDevices.
// - Different from the id of the route published by the device under test (usually the
// built-in speakers).
@@ -547,6 +590,7 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
assertThat(devices.containsAll(mMediaDevices)).isTrue();
assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+ // There should be 1 non-MediaDevice item: the "Speakers & Display" title.
assertThat(mMediaSwitchingController.getMediaItemList().size())
.isEqualTo(mMediaDevices.size() + 1);
verify(mCb).onDeviceListChanged();
@@ -554,6 +598,45 @@ public class MediaSwitchingControllerTest extends SysuiTestCase {
@EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
@Test
+ public void advanced_onDeviceListUpdateWithConnectedDeviceRemote_verifyItemSize_inputRouting() {
+ // This test relies on mMediaSwitchingController.start being called while the selected
+ // device list has exactly one item, and that item's id is:
+ // - Different from both ids in mMediaDevices.
+ // - Different from the id of the route published by the device under test (usually the
+ // built-in speakers).
+ // So mock the selected device to respect these two preconditions.
+ MediaDevice mockSelectedMediaDevice = Mockito.mock(MediaDevice.class);
+ when(mockSelectedMediaDevice.getId()).thenReturn(TEST_DEVICE_3_ID);
+ doReturn(List.of(mockSelectedMediaDevice))
+ .when(mLocalMediaManager)
+ .getSelectedMediaDevice();
+
+ when(mMediaDevice1.getFeatures())
+ .thenReturn(ImmutableList.of(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK));
+ when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(mMediaDevice1);
+ mMediaSwitchingController.start(mCb);
+ reset(mCb);
+
+ mMediaSwitchingController.onDeviceListUpdate(mMediaDevices);
+ final List<MediaDevice> devices = new ArrayList<>();
+ for (MediaItem item : mMediaSwitchingController.getMediaItemList()) {
+ if (item.getMediaDevice().isPresent()) {
+ devices.add(item.getMediaDevice().get());
+ }
+ }
+
+ assertThat(devices.containsAll(mMediaDevices)).isTrue();
+ assertThat(devices.size()).isEqualTo(mMediaDevices.size());
+ // When input routing is enabled, there should be 3 non-MediaDevice items: one for
+ // the "Output" title, one for the "Speakers & Displays" title, and one for the "Input"
+ // title.
+ assertThat(mMediaSwitchingController.getMediaItemList().size())
+ .isEqualTo(mMediaDevices.size() + 3);
+ verify(mCb).onDeviceListChanged();
+ }
+
+ @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
+ @Test
public void onInputDeviceListUpdate_verifyDeviceListCallback() {
AudioDeviceInfo[] audioDeviceInfos = {};
when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS))
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
index e36ad427b43e..35e85bb1e68d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelKosmos.kt
@@ -18,6 +18,7 @@ package com.android.systemui.brightness.ui.viewmodel
import com.android.systemui.brightness.domain.interactor.brightnessPolicyEnforcementInteractor
import com.android.systemui.brightness.domain.interactor.screenBrightnessInteractor
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor
@@ -33,6 +34,7 @@ val Kosmos.brightnessSliderViewModelFactory: BrightnessSliderViewModel.Factory b
hapticsViewModelFactory = sliderHapticsViewModelFactory,
brightnessMirrorShowingInteractor = brightnessMirrorShowingInteractor,
supportsMirroring = allowsMirroring,
+ falsingInteractor = falsingInteractor,
brightnessWarningToast = brightnessWarningToast,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt
index b24b3ad05117..71746b505a48 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/dreams/ui/viewmodel/DreamUserActionsViewModelKosmos.kt
@@ -16,6 +16,7 @@
package com.android.systemui.dreams.ui.viewmodel
+import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.shade.domain.interactor.shadeInteractor
@@ -23,6 +24,7 @@ import com.android.systemui.shade.domain.interactor.shadeInteractor
val Kosmos.dreamUserActionsViewModel by
Kosmos.Fixture {
DreamUserActionsViewModel(
+ communalInteractor = communalInteractor,
deviceUnlockedInteractor = deviceUnlockedInteractor,
shadeInteractor = shadeInteractor,
)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
index 721c0b8339db..2c8581608739 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -102,10 +102,7 @@ val Kosmos.defaultShortcutCategoriesRepository by
)
}
-val Kosmos.inputGestureMaps by
- Kosmos.Fixture {
- InputGestureMaps(applicationContext)
- }
+val Kosmos.inputGestureMaps by Kosmos.Fixture { InputGestureMaps(applicationContext) }
val Kosmos.customShortcutCategoriesRepository by
Kosmos.Fixture {
@@ -116,7 +113,7 @@ val Kosmos.customShortcutCategoriesRepository by
testDispatcher,
shortcutCategoriesUtils,
applicationContext,
- inputGestureMaps
+ inputGestureMaps,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
index b5e6f75c7915..c0b39b1df7d5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
+import android.content.applicationContext
import android.content.res.mainResources
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
@@ -28,12 +29,13 @@ import com.android.systemui.statusbar.ui.systemBarUtilsProxy
val Kosmos.keyguardClockViewModel by
Kosmos.Fixture {
KeyguardClockViewModel(
+ context = applicationContext,
keyguardClockInteractor = keyguardClockInteractor,
applicationScope = applicationCoroutineScope,
aodNotificationIconViewModel = notificationIconContainerAlwaysOnDisplayViewModel,
shadeInteractor = shadeInteractor,
systemBarUtils = systemBarUtilsProxy,
configurationInteractor = configurationInteractor,
- resources = mainResources
+ resources = mainResources,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt
index a25b29fd18cb..2311c0a23db8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenUserActionsViewModelKosmos.kt
@@ -20,6 +20,7 @@ import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.shade.domain.interactor.shadeInteractor
val Kosmos.lockscreenUserActionsViewModel by Fixture {
@@ -27,5 +28,6 @@ val Kosmos.lockscreenUserActionsViewModel by Fixture {
deviceEntryInteractor = deviceEntryInteractor,
communalInteractor = communalInteractor,
shadeInteractor = shadeInteractor,
+ occlusionInteractor = sceneContainerOcclusionInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
index 72cb1dfe38db..1556058d51ba 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
@@ -1,8 +1,12 @@
package com.android.systemui.kosmos
import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.FlowValue
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.settings.brightness.ui.BrightnessWarningToast
+import com.android.systemui.util.mockito.mock
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.test.StandardTestDispatcher
@@ -32,12 +36,15 @@ fun Kosmos.useStandardTestDispatcher() = apply { testDispatcher = StandardTestDi
fun Kosmos.useUnconfinedTestDispatcher() = apply { testDispatcher = UnconfinedTestDispatcher() }
var Kosmos.testScope by Fixture { TestScope(testDispatcher) }
-var Kosmos.applicationCoroutineScope by Fixture { testScope.backgroundScope }
+var Kosmos.backgroundScope by Fixture { testScope.backgroundScope }
+var Kosmos.applicationCoroutineScope by Fixture { backgroundScope }
var Kosmos.testCase: SysuiTestCase by Fixture()
var Kosmos.backgroundCoroutineContext: CoroutineContext by Fixture {
- testScope.backgroundScope.coroutineContext
+ backgroundScope.coroutineContext
}
var Kosmos.mainCoroutineContext: CoroutineContext by Fixture { testScope.coroutineContext }
+var Kosmos.brightnessWarningToast: BrightnessWarningToast by
+ Kosmos.Fixture { mock<BrightnessWarningToast>() }
/**
* Run this test body with a [Kosmos] as receiver, and using the [testScope] currently installed in
@@ -49,3 +56,5 @@ fun Kosmos.runTest(testBody: suspend Kosmos.() -> Unit) =
fun Kosmos.runCurrent() = testScope.runCurrent()
fun <T> Kosmos.collectLastValue(flow: Flow<T>) = testScope.collectLastValue(flow)
+
+fun <T> Kosmos.collectValues(flow: Flow<T>): FlowValue<List<T>> = testScope.collectValues(flow)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/FakeMediaProjectionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/FakeMediaProjectionRepository.kt
index d631f926176d..e6256a58a365 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/FakeMediaProjectionRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/mediaprojection/data/repository/FakeMediaProjectionRepository.kt
@@ -17,6 +17,7 @@
package com.android.systemui.mediaprojection.data.repository
import android.app.ActivityManager
+import android.media.projection.StopReason
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import kotlinx.coroutines.flow.MutableStateFlow
@@ -28,7 +29,7 @@ class FakeMediaProjectionRepository : MediaProjectionRepository {
var stopProjectingInvoked = false
- override suspend fun stopProjecting() {
+ override suspend fun stopProjecting(@StopReason stopReason: Int) {
stopProjectingInvoked = true
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
index 45d5b387fea0..c574463eb258 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
@@ -18,10 +18,12 @@ package com.android.systemui.qs.composefragment.viewmodel
import android.content.res.mainResources
import androidx.lifecycle.LifecycleCoroutineScope
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.table.logcatTableLogBuffer
import com.android.systemui.media.controls.ui.view.qqsMediaHost
import com.android.systemui.media.controls.ui.view.qsMediaHost
import com.android.systemui.qs.composefragment.dagger.usingMediaInComposeFragment
@@ -57,7 +59,9 @@ val Kosmos.qsFragmentComposeViewModelFactory by
configurationInteractor,
largeScreenHeaderHelper,
tileSquishinessInteractor,
+ falsingInteractor,
inFirstPageViewModel,
+ logcatTableLogBuffer(this@Fixture),
mediaInRowInLandscapeViewModelFactory,
qqsMediaHost,
qsMediaHost,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.kt
new file mode 100644
index 000000000000..b8d3ff425f20
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeButtonViewModelKosmos.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.qs.panels.ui.viewmodel
+
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.editModeButtonViewModelFactory by
+ Kosmos.Fixture {
+ object : EditModeButtonViewModel.Factory {
+ override fun create(): EditModeButtonViewModel {
+ return EditModeButtonViewModel(editModeViewModel, falsingInteractor)
+ }
+ }
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
index 2e80293eafff..5c71ba2f8bbd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
@@ -16,6 +16,7 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.development.ui.viewmodel.buildNumberViewModelFactory
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.panels.domain.interactor.paginatedGridInteractor
@@ -28,5 +29,7 @@ val Kosmos.paginatedGridViewModel by
paginatedGridInteractor,
inFirstPageViewModel,
buildNumberViewModelFactory,
+ editModeButtonViewModelFactory,
+ falsingInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorKosmos.kt
new file mode 100644
index 000000000000..12d4e90dc469
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/DisabledContentInteractorKosmos.kt
@@ -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.
+ */
+
+package com.android.systemui.scene.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.statusbar.disableflags.domain.interactor.disableFlagsInteractor
+
+val Kosmos.disabledContentInteractor by Fixture {
+ DisabledContentInteractor(disableFlagsInteractor = disableFlagsInteractor)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
index f84c3bdfdaf1..eb352baab0e4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
@@ -33,5 +33,6 @@ val Kosmos.sceneInteractor: SceneInteractor by
sceneFamilyResolvers = { sceneFamilyResolvers },
deviceUnlockedInteractor = { deviceUnlockedInteractor },
keyguardEnabledInteractor = { keyguardEnabledInteractor },
+ disabledContentInteractor = disabledContentInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
index 7e6a7271c561..82b5f6332b23 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
@@ -37,6 +37,7 @@ import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.testScope
import com.android.systemui.model.sysUiState
import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.domain.interactor.disabledContentInteractor
import com.android.systemui.scene.domain.interactor.sceneBackInteractor
import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -83,5 +84,6 @@ val Kosmos.sceneContainerStartable by Fixture {
alternateBouncerInteractor = alternateBouncerInteractor,
vibratorHelper = vibratorHelper,
msdlPlayer = msdlPlayer,
+ disabledContentInteractor = disabledContentInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt
index 090ce31bd43c..951ae59ebcf1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/AutoHideKosmos.kt
@@ -16,9 +16,36 @@
package com.android.systemui.statusbar.phone
+import android.content.Context
+import android.os.Handler
+import android.view.IWindowManager
+import com.android.systemui.display.data.repository.displayRepository
+import com.android.systemui.display.data.repository.fakeDisplayWindowPropertiesRepository
import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.util.mockito.mock
+import com.android.systemui.kosmos.applicationCoroutineScope
+import org.mockito.Mockito.mock
-val Kosmos.mockAutoHideController by Kosmos.Fixture { mock<AutoHideController>() }
+val Kosmos.mockAutoHideController: AutoHideController by
+ Kosmos.Fixture { mock(AutoHideController::class.java) }
var Kosmos.autoHideController by Kosmos.Fixture { mockAutoHideController }
+
+val Kosmos.fakeAutoHideControllerFactory by Kosmos.Fixture { FakeAutoHideControllerFactory() }
+
+val Kosmos.multiDisplayAutoHideControllerStore by
+ Kosmos.Fixture {
+ MultiDisplayAutoHideControllerStore(
+ applicationCoroutineScope,
+ displayRepository,
+ fakeDisplayWindowPropertiesRepository,
+ fakeAutoHideControllerFactory,
+ )
+ }
+
+class FakeAutoHideControllerFactory :
+ AutoHideControllerImpl.Factory(mock(Handler::class.java), mock(IWindowManager::class.java)) {
+
+ override fun create(context: Context): AutoHideControllerImpl {
+ return mock(AutoHideControllerImpl::class.java)
+ }
+}
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/Android.bp b/ravenwood/tools/hoststubgen/test-tiny-framework/Android.bp
index 1570549ec27d..483c4be7633b 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/Android.bp
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/Android.bp
@@ -156,6 +156,7 @@ python_test_host {
],
data: [
"golden-output/*.txt",
+ "golden-output.RELEASE_TARGET_JAVA_21/*.txt",
],
java_data: [
"hoststubgen-test-tiny-framework-orig-dump",
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt
new file mode 100644
index 000000000000..5e5ca62b49f0
--- /dev/null
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt
@@ -0,0 +1,3697 @@
+## Class: android/hosttest/annotation/HostSideTestClassLoadHook.class
+ Compiled from "HostSideTestClassLoadHook.java"
+public interface android.hosttest.annotation.HostSideTestClassLoadHook extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestIgnore.class
+ Compiled from "HostSideTestIgnore.java"
+public interface android.hosttest.annotation.HostSideTestIgnore extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestIgnore
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestIgnore.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestKeep.class
+ Compiled from "HostSideTestKeep.java"
+public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRedirect.class
+ Compiled from "HostSideTestRedirect.java"
+public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestRedirect.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRedirectionClass.class
+ Compiled from "HostSideTestRedirectionClass.java"
+public interface android.hosttest.annotation.HostSideTestRedirectionClass extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestRedirectionClass.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRemove.class
+ Compiled from "HostSideTestRemove.java"
+public interface android.hosttest.annotation.HostSideTestRemove extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRemove
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestRemove.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestStaticInitializerKeep.class
+ Compiled from "HostSideTestStaticInitializerKeep.java"
+public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestStaticInitializerKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestSubstitute.class
+ Compiled from "HostSideTestSubstitute.java"
+public interface android.hosttest.annotation.HostSideTestSubstitute extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String suffix();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestSubstitute.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestThrow.class
+ Compiled from "HostSideTestThrow.java"
+public interface android.hosttest.annotation.HostSideTestThrow extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestThrow
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestThrow.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassKeep.class
+ Compiled from "HostSideTestWholeClassKeep.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestWholeClassKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/tests/HostSideTestSuppress.class
+ Compiled from "HostSideTestSuppress.java"
+public interface android.hosttest.annotation.tests.HostSideTestSuppress extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/tests/HostSideTestSuppress
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestSuppress.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD]
+ )
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
+ Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
+ 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/IPretendingAidl$Stub$Proxy;
+
+ public static int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 a I
+}
+SourceFile: "IPretendingAidl.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+InnerClasses:
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub.class
+ Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub();
+ 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/IPretendingAidl$Stub;
+
+ public static int addOne(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 a I
+}
+SourceFile: "IPretendingAidl.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+InnerClasses:
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl.class
+ Compiled from "IPretendingAidl.java"
+public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 3
+}
+SourceFile: "IPretendingAidl.java"
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+InnerClasses:
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+## Class: com/android/hoststubgen/test/tinyframework/R$Nested.class
+ Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R$Nested
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/R$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 3
+ public static int[] ARRAY;
+ descriptor: [I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+
+ public com.android.hoststubgen.test.tinyframework.R$Nested();
+ 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/R$Nested;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: iconst_1
+ x: newarray int
+ x: dup
+ x: iconst_0
+ x: iconst_1
+ x: iastore
+ x: putstatic #x // Field ARRAY:[I
+ x: return
+ LineNumberTable:
+}
+SourceFile: "R.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/R
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+## Class: com/android/hoststubgen/test/tinyframework/R.class
+ Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/R
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.R();
+ 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/R;
+}
+SourceFile: "R.java"
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/R$Nested
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class
+ Compiled from "TinyFrameworkAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 9, attributes: 2
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ 0 4 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ 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/TinyFrameworkAnnotations;
+ 0 8 1 foo Ljava/lang/String;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRemove
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String not supported on host side
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ 0 10 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestSubstitute(
+ suffix="_host"
+ )
+
+ public int addTwo_host(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ 0 4 1 value I
+
+ public static native int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestSubstitute(
+ suffix="_host"
+ )
+
+ private static int nativeAddThree_host(int);
+ descriptor: (I)I
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: ldc #x // String This value shouldn\'t be seen on the host side.
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+
+ public int toBeIgnored();
+ 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 not supported on host side
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestIgnore
+}
+SourceFile: "TinyFrameworkAnnotations.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+ Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 2
+ public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+ descriptor: Ljava/util/Set;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/Set<Ljava/lang/Class<*>;>;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ 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/TinyFrameworkClassLoadHook;
+
+ public static void onClassLoaded(java.lang.Class<?>);
+ descriptor: (Ljava/lang/Class;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: getstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: aload_0
+ x: invokeinterface #x, 2 // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
+ x: pop
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 clazz Ljava/lang/Class;
+ LocalVariableTypeTable:
+ Start Length Slot Name Signature
+ 0 11 0 clazz Ljava/lang/Class<*>;
+ Signature: #x // (Ljava/lang/Class<*>;)V
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class java/util/HashSet
+ x: dup
+ x: invokespecial #x // Method java/util/HashSet."<init>":()V
+ x: putstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class
+ Compiled from "TinyFrameworkClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 6, attributes: 2
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRemove
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+ 0 4 1 value I
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String not supported on host side
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+ 0 10 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestSubstitute(
+ suffix="_host"
+ )
+
+ public int addTwo_host(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+ 0 4 1 value I
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ 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/TinyFrameworkClassWideAnnotations;
+ 0 8 1 foo Ljava/lang/String;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRemove
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: ldc #x // String This value shouldn\'t be seen on the host side.
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+}
+SourceFile: "TinyFrameworkClassWideAnnotations.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+ Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 2, attributes: 2
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault();
+ 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/TinyFrameworkClassWithInitializerDefault;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: iconst_1
+ x: putstatic #x // Field sInitialized:Z
+ x: new #x // class java/lang/Object
+ x: dup
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: putstatic #x // Field sObject:Ljava/lang/Object;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+ Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 2, attributes: 2
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub();
+ 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/TinyFrameworkClassWithInitializerStub;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: iconst_1
+ x: putstatic #x // Field sInitialized:Z
+ x: new #x // class java/lang/Object
+ x: dup
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: putstatic #x // Field sObject:Ljava/lang/Object;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+ Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+ minor version: 0
+ major version: 65
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 6, methods: 7, attributes: 3
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private final java.lang.String mLongName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private final java.lang.String mShortName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;"
+ x: areturn
+ LineNumberTable:
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 name Ljava/lang/String;
+ MethodParameters:
+ Name Flags
+ <no name> mandated
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+ descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=5, args_size=5
+ x: aload_0
+ x: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: aload_0
+ x: aload_3
+ x: putfield #x // Field mLongName:Ljava/lang/String;
+ x: aload_0
+ x: aload 4
+ x: putfield #x // Field mShortName:Ljava/lang/String;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 18 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ 0 18 3 longName Ljava/lang/String;
+ 0 18 4 shortName Ljava/lang/String;
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+ <no name>
+ <no name>
+ Signature: #x // (Ljava/lang/String;Ljava/lang/String;)V
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public java.lang.String getLongName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mLongName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public java.lang.String getShortName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mShortName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: iconst_3
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_2
+ x: getstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=6, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String RED
+ x: iconst_0
+ x: ldc #x // String Red
+ x: ldc #x // String R
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String GREEN
+ x: iconst_1
+ x: ldc #x // String Green
+ x: ldc #x // String G
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String BLUE
+ x: iconst_2
+ x: ldc #x // String Blue
+ x: ldc #x // String B
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: return
+ LineNumberTable:
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+ Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+ minor version: 0
+ major version: 65
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 3, methods: 5, attributes: 3
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;"
+ x: areturn
+ LineNumberTable:
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 name Ljava/lang/String;
+ MethodParameters:
+ Name Flags
+ <no name> mandated
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+ descriptor: (Ljava/lang/String;I)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=3, args_size=3
+ x: aload_0
+ x: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 7 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+ Signature: #x // ()V
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: iconst_2
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String CAT
+ x: iconst_0
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String DOG
+ x: iconst_1
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: return
+ LineNumberTable:
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+ Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 2
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+ 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/TinyFrameworkExceptionTester;
+
+ public static int testException();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=0
+ x: new #x // class java/lang/IllegalStateException
+ x: dup
+ x: ldc #x // String Inner exception
+ x: invokespecial #x // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ x: astore_0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Outer exception
+ x: aload_0
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;Ljava/lang/Throwable;)V
+ x: athrow
+ Exception table:
+ from to target type
+ 0 10 10 Class java/lang/Exception
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 e Ljava/lang/Exception;
+ StackMapTable: number_of_entries = 1
+ frame_type = 74 /* same_locals_1_stack_item */
+ stack = [ class java/lang/Exception ]
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+ Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+ minor version: 0
+ major version: 65
+ 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: 17, attributes: 1
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 4 1 value I
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ 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;
+ 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
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String not supported on host side
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 10 1 value I
+
+ public int addTwo_host(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 4 1 value I
+
+ public static native int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static int addThree_host(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: ldc #x // String This value shouldn\'t be seen on the host side.
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 8
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 6
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_5
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$static$1:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+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/TinyFrameworkLambdas.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$static$1:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+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: 65
+ 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: 65
+ 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.HostSideTestWholeClassKeep
+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
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 14, attributes: 2
+ int value;
+ descriptor: I
+ flags: (0x0000)
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+ 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/TinyFrameworkNative;
+
+ public static native int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public static int nativeAddTwo_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 arg I
+
+ public static native long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public static long nativeLongPlus_should_be_like_this(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 arg1 J
+ 0 6 2 arg2 J
+
+ public void setValue(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 6 1 v I
+
+ public native int nativeNonStaticAddToValue(int);
+ descriptor: (I)I
+ flags: (0x0101) ACC_PUBLIC, ACC_NATIVE
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public int nativeNonStaticAddToValue_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 6 1 arg I
+
+ public static native void nativeStillNotSupported();
+ descriptor: ()V
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+
+ public static native void nativeStillKeep();
+ descriptor: ()V
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static void nativeStillNotSupported_should_be_like_this();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+
+ public static native byte nativeBytePlus(byte, byte);
+ descriptor: (BB)B
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public void notNativeRedirected();
+ 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/TinyFrameworkNative;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public static void notNativeStaticRedirected();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestRedirectionClass(
+ value="TinyFrameworkNative_host"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.class
+ Compiled from "TinyFrameworkNative_host.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 7, attributes: 2
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
+ 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/TinyFrameworkNative_host;
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 arg I
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: ladd
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 arg1 J
+ 0 4 2 arg2 J
+
+ public static int nativeNonStaticAddToValue(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative, int);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: getfield #x // Field com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.value:I
+ x: iload_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 7 0 source Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 7 1 arg I
+
+ public static byte nativeBytePlus(byte, byte);
+ descriptor: (BB)B
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_0
+ x: iload_1
+ x: iadd
+ x: i2b
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 arg1 B
+ 0 5 1 arg2 B
+
+ public static void notNativeRedirected(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=0, locals=1, args_size=1
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 1 0 source Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+
+ public static void notNativeStaticRedirected();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=0, locals=0, args_size=0
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkNative_host.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 5
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=1, locals=2, args_size=2
+ 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/TinyFrameworkNestedClasses$1;
+ 0 5 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+}
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 5
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
+ descriptor: ()V
+ flags: (0x0000)
+ 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/TinyFrameworkNestedClasses$2;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+}
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 5
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=1, locals=2, args_size=2
+ 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/TinyFrameworkNestedClasses$3;
+ 0 5 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+}
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 5
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
+ descriptor: ()V
+ flags: (0x0000)
+ 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/TinyFrameworkNestedClasses$4;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+}
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier_static
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 3
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass;
+ 0 10 1 x I
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 3
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_5
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
+ 0 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 5
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
+ descriptor: ()V
+ flags: (0x0000)
+ 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/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+}
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass.getSupplier_static
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 3
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: bipush 8
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass;
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 3
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: bipush 6
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ interfaces: 0, fields: 0, methods: 1, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass."<init>":(I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass;
+ 0 6 1 x I
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 4, attributes: 4
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 17 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 9 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2."<init>":()V
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+ Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 2
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
+ 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/TinyFrameworkPackageRedirect;
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/unsupported/UnsupportedClass
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method com/unsupported/UnsupportedClass."<init>":(I)V
+ x: invokevirtual #x // Method com/unsupported/UnsupportedClass.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 12 0 value I
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
+ Compiled from "TinyFrameworkRenamedClassCaller.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 2
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller();
+ 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/TinyFrameworkRenamedClassCaller;
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed."<init>":(I)V
+ x: invokevirtual #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 12 0 value I
+}
+SourceFile: "TinyFrameworkRenamedClassCaller.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.class
+ Compiled from "TinyFrameworkToBeRenamed.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 2
+ private final int mValue;
+ descriptor: I
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field mValue:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 0 10 1 value I
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mValue:I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+}
+SourceFile: "TinyFrameworkToBeRenamed.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/A.class
+ Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.A
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/A
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.packagetest.A();
+ 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/packagetest/A;
+}
+SourceFile: "A.java"
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/B.class
+ Compiled from "B.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.B
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/B
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.packagetest.B();
+ 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/packagetest/B;
+}
+SourceFile: "B.java"
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/sub/A.class
+ Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.packagetest.sub.A();
+ 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/packagetest/sub/A;
+}
+SourceFile: "A.java"
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/sub/B.class
+ Compiled from "B.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.sub.B
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/B
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.packagetest.sub.B();
+ 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/packagetest/sub/B;
+}
+SourceFile: "B.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class
+ Compiled from "C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.C1();
+ 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/subclasstest/C1;
+}
+SourceFile: "C1.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class
+ Compiled from "C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.C2();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/C1."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/C2;
+}
+SourceFile: "C2.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class
+ Compiled from "C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.C3();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/C2."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/C3;
+}
+SourceFile: "C3.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class
+ Compiled from "CA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.CA();
+ 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/subclasstest/CA;
+}
+SourceFile: "CA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class
+ Compiled from "CB.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.CB();
+ 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/subclasstest/CB;
+}
+SourceFile: "CB.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.class
+ Compiled from "Class_C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/C1."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_C1;
+}
+SourceFile: "Class_C1.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.class
+ Compiled from "Class_C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/C2."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_C2;
+}
+SourceFile: "Class_C2.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.class
+ Compiled from "Class_C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C3
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/C3."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_C3;
+}
+SourceFile: "Class_C3.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA.class
+ Compiled from "Class_CA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CA extends com.android.hoststubgen.test.tinyframework.subclasstest.CA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CA();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/CA."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_CA;
+}
+SourceFile: "Class_CA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB.class
+ Compiled from "Class_CB.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB extends com.android.hoststubgen.test.tinyframework.subclasstest.CB
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/CB."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_CB;
+}
+SourceFile: "Class_CB.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA.class
+ Compiled from "Class_CB_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB_IA extends com.android.hoststubgen.test.tinyframework.subclasstest.CB implements com.android.hoststubgen.test.tinyframework.subclasstest.IA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
+ interfaces: 1, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB_IA();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/subclasstest/CB."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA;
+}
+SourceFile: "Class_CB_IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.class
+ Compiled from "Class_I1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.I1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1();
+ 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/subclasstest/Class_I1;
+}
+SourceFile: "Class_I1.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.class
+ Compiled from "Class_I1_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I1,com.android.hoststubgen.test.tinyframework.subclasstest.IA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
+ super_class: #x // java/lang/Object
+ interfaces: 2, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA();
+ 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/subclasstest/Class_I1_IA;
+}
+SourceFile: "Class_I1_IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.class
+ Compiled from "Class_I2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 implements com.android.hoststubgen.test.tinyframework.subclasstest.I2
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2();
+ 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/subclasstest/Class_I2;
+}
+SourceFile: "Class_I2.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.class
+ Compiled from "Class_I3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.I3
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3();
+ 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/subclasstest/Class_I3;
+}
+SourceFile: "Class_I3.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA.class
+ Compiled from "Class_I3_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I3,com.android.hoststubgen.test.tinyframework.subclasstest.IA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA
+ super_class: #x // java/lang/Object
+ interfaces: 2, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3_IA();
+ 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/subclasstest/Class_I3_IA;
+}
+SourceFile: "Class_I3_IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA.class
+ Compiled from "Class_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.IA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA();
+ 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/subclasstest/Class_IA;
+}
+SourceFile: "Class_IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1.class
+ Compiled from "Class_IA_I1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.IA,com.android.hoststubgen.test.tinyframework.subclasstest.I1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1
+ super_class: #x // java/lang/Object
+ interfaces: 2, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I1();
+ 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/subclasstest/Class_IA_I1;
+}
+SourceFile: "Class_IA_I1.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3.class
+ Compiled from "Class_IA_I3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.IA,com.android.hoststubgen.test.tinyframework.subclasstest.I3
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3
+ super_class: #x // java/lang/Object
+ interfaces: 2, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I3();
+ 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/subclasstest/Class_IA_I3;
+}
+SourceFile: "Class_IA_I3.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB.class
+ Compiled from "Class_IB.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB implements com.android.hoststubgen.test.tinyframework.subclasstest.IB
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB();
+ 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/subclasstest/Class_IB;
+}
+SourceFile: "Class_IB.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA.class
+ Compiled from "Class_IB_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.IB,com.android.hoststubgen.test.tinyframework.subclasstest.IA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA
+ super_class: #x // java/lang/Object
+ interfaces: 2, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB_IA();
+ 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/subclasstest/Class_IB_IA;
+}
+SourceFile: "Class_IB_IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_None.class
+ Compiled from "Class_None.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_None
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_None
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 1
+ public com.android.hoststubgen.test.tinyframework.subclasstest.Class_None();
+ 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/subclasstest/Class_None;
+}
+SourceFile: "Class_None.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class
+ Compiled from "I1.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 1
+}
+SourceFile: "I1.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class
+ Compiled from "I2.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 1
+}
+SourceFile: "I2.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class
+ Compiled from "I3.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 1
+}
+SourceFile: "I3.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class
+ Compiled from "IA.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 1
+}
+SourceFile: "IA.java"
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class
+ Compiled from "IB.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 1
+}
+SourceFile: "IB.java"
+## Class: com/supported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.supported.UnsupportedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/supported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 2
+ private final int mValue;
+ descriptor: I
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+
+ public com.supported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field mValue:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/supported/UnsupportedClass;
+ 0 10 1 value I
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mValue:I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/supported/UnsupportedClass;
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/unsupported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/unsupported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 2
+ public com.unsupported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/unsupported/UnsupportedClass;
+ 0 14 1 value I
+
+ public int getValue();
+ 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 This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/unsupported/UnsupportedClass;
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt
new file mode 100644
index 000000000000..84a8373008d7
--- /dev/null
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt
@@ -0,0 +1,3727 @@
+## Class: android/hosttest/annotation/HostSideTestClassLoadHook.class
+ Compiled from "HostSideTestClassLoadHook.java"
+public interface android.hosttest.annotation.HostSideTestClassLoadHook extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestKeep.class
+ Compiled from "HostSideTestKeep.java"
+public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRedirect.class
+ Compiled from "HostSideTestRedirect.java"
+public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestRedirect.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRedirectionClass.class
+ Compiled from "HostSideTestRedirectionClass.java"
+public interface android.hosttest.annotation.HostSideTestRedirectionClass extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestRedirectionClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRemove.class
+ Compiled from "HostSideTestRemove.java"
+public interface android.hosttest.annotation.HostSideTestRemove extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRemove
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestRemove.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestStaticInitializerKeep.class
+ Compiled from "HostSideTestStaticInitializerKeep.java"
+public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestStaticInitializerKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestSubstitute.class
+ Compiled from "HostSideTestSubstitute.java"
+public interface android.hosttest.annotation.HostSideTestSubstitute extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String suffix();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestSubstitute.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestThrow.class
+ Compiled from "HostSideTestThrow.java"
+public interface android.hosttest.annotation.HostSideTestThrow extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestThrow
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestThrow.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassKeep.class
+ Compiled from "HostSideTestWholeClassKeep.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestWholeClassKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
+ Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
+ 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/IPretendingAidl$Stub$Proxy;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 a I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub.class
+ Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub();
+ 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/IPretendingAidl$Stub;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int addOne(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 a I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl.class
+ Compiled from "IPretendingAidl.java"
+public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 4
+}
+InnerClasses:
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+## Class: com/android/hoststubgen/test/tinyframework/R$Nested.class
+ Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R$Nested
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/R$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+ public static int[] ARRAY;
+ descriptor: [I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.R$Nested();
+ 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/R$Nested;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: iconst_1
+ x: newarray int
+ x: dup
+ x: iconst_0
+ x: iconst_1
+ x: iastore
+ x: putstatic #x // Field ARRAY:[I
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+SourceFile: "R.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/R
+## Class: com/android/hoststubgen/test/tinyframework/R.class
+ Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/R
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.R();
+ 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/R;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+SourceFile: "R.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/R$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class
+ Compiled from "TinyFrameworkAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 7, attributes: 3
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ 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/TinyFrameworkAnnotations
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ 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.TinyFrameworkAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ 0 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ 0 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ 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: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+
+ public int toBeIgnored();
+ 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.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestIgnore
+}
+SourceFile: "TinyFrameworkAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+ Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+ descriptor: Ljava/util/Set;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/Set<Ljava/lang/Class<*>;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ 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/TinyFrameworkClassLoadHook;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static void onClassLoaded(java.lang.Class<?>);
+ descriptor: (Ljava/lang/Class;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: getstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: aload_0
+ x: invokeinterface #x, 2 // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
+ x: pop
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 clazz Ljava/lang/Class;
+ LocalVariableTypeTable:
+ Start Length Slot Name Signature
+ 0 11 0 clazz Ljava/lang/Class<*>;
+ Signature: #x // (Ljava/lang/Class<*>;)V
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class java/util/HashSet
+ x: dup
+ x: invokespecial #x // Method java/util/HashSet."<init>":()V
+ x: putstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class
+ Compiled from "TinyFrameworkClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 4, attributes: 3
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+ 0 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+ 0 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ 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: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+}
+SourceFile: "TinyFrameworkClassWideAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+ Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 0, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+ Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 1, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: iconst_1
+ x: putstatic #x // Field sInitialized:Z
+ x: new #x // class java/lang/Object
+ x: dup
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: putstatic #x // Field sObject:Ljava/lang/Object;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+ Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+ minor version: 0
+ major version: 65
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 6, methods: 7, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private final java.lang.String mLongName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private final java.lang.String mShortName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;"
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 name Ljava/lang/String;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> mandated
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+ descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=5, args_size=5
+ x: aload_0
+ x: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: aload_0
+ x: aload_3
+ x: putfield #x // Field mLongName:Ljava/lang/String;
+ x: aload_0
+ x: aload 4
+ x: putfield #x // Field mShortName:Ljava/lang/String;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 18 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ 0 18 3 longName Ljava/lang/String;
+ 0 18 4 shortName Ljava/lang/String;
+ Signature: #x // (Ljava/lang/String;Ljava/lang/String;)V
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+ <no name>
+ <no name>
+
+ public java.lang.String getLongName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mLongName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public java.lang.String getShortName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mShortName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: iconst_3
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_2
+ x: getstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=6, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String RED
+ x: iconst_0
+ x: ldc #x // String Red
+ x: ldc #x // String R
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String GREEN
+ x: iconst_1
+ x: ldc #x // String Green
+ x: ldc #x // String G
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String BLUE
+ x: iconst_2
+ x: ldc #x // String Blue
+ x: ldc #x // String B
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+ Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+ minor version: 0
+ major version: 65
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 3, methods: 5, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;"
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 name Ljava/lang/String;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> mandated
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+ descriptor: (Ljava/lang/String;I)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=3, args_size=3
+ x: aload_0
+ x: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 7 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ Signature: #x // ()V
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: iconst_2
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String CAT
+ x: iconst_0
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String DOG
+ x: iconst_1
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+ Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+ 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/TinyFrameworkExceptionTester;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int testException();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=0
+ x: new #x // class java/lang/IllegalStateException
+ x: dup
+ x: ldc #x // String Inner exception
+ x: invokespecial #x // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ x: astore_0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Outer exception
+ x: aload_0
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;Ljava/lang/Throwable;)V
+ x: athrow
+ Exception table:
+ from to target type
+ 0 10 10 Class java/lang/Exception
+ StackMapTable: number_of_entries = 1
+ frame_type = 74 /* same_locals_1_stack_item */
+ stack = [ class java/lang/Exception ]
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 e Ljava/lang/Exception;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+ Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+ minor version: 0
+ major version: 65
+ 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: 15, attributes: 2
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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/TinyFrameworkForTextPolicy
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ 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.TinyFrameworkForTextPolicy();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ 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: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 6
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 8
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 6
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_5
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+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
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$static$1:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 6
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+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
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$static$1:()Ljava/lang/Integer;
+ #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: 65
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+}
+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.HostStubGenProcessedAsKeep
+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: 65
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+}
+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.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+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
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 14, attributes: 3
+ int value;
+ descriptor: I
+ flags: (0x0000)
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+ 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/TinyFrameworkNative;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public static int nativeAddTwo_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 arg I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public static long nativeLongPlus_should_be_like_this(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 arg1 J
+ 0 6 2 arg2 J
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public void setValue(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 6 1 v I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int nativeNonStaticAddToValue(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public int nativeNonStaticAddToValue_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 6 1 arg I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static void nativeStillNotSupported();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ 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: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+
+ public static native void nativeStillKeep();
+ descriptor: ()V
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static void nativeStillNotSupported_should_be_like_this();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static byte nativeBytePlus(byte, byte);
+ descriptor: (BB)B
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeBytePlus:(BB)B
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public void notNativeRedirected();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.notNativeRedirected:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+ x: return
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public static void notNativeStaticRedirected();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=0, locals=0, args_size=0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.notNativeStaticRedirected:()V
+ x: return
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestRedirectionClass(
+ value="TinyFrameworkNative_host"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.class
+ Compiled from "TinyFrameworkNative_host.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 7, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
+ 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/TinyFrameworkNative_host;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 arg I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: ladd
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 arg1 J
+ 0 4 2 arg2 J
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int nativeNonStaticAddToValue(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative, int);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: getfield #x // Field com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.value:I
+ x: iload_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 7 0 source Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 7 1 arg I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static byte nativeBytePlus(byte, byte);
+ descriptor: (BB)B
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_0
+ x: iload_1
+ x: iadd
+ x: i2b
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 arg1 B
+ 0 5 1 arg2 B
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static void notNativeRedirected(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=0, locals=1, args_size=1
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 1 0 source Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static void notNativeStaticRedirected();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=0, locals=0, args_size=0
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkNative_host.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 6
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=1, locals=2, args_size=2
+ 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/TinyFrameworkNestedClasses$1;
+ 0 5 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 6
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
+ descriptor: ()V
+ flags: (0x0000)
+ 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/TinyFrameworkNestedClasses$2;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 6
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=1, locals=2, args_size=2
+ 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/TinyFrameworkNestedClasses$3;
+ 0 5 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 6
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
+ descriptor: ()V
+ flags: (0x0000)
+ 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/TinyFrameworkNestedClasses$4;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier_static
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass;
+ 0 10 1 x I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_5
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
+ 0 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
+}
+InnerClasses:
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 6
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
+ descriptor: ()V
+ flags: (0x0000)
+ 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/TinyFrameworkNestedClasses$StaticNestedClass$1;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass.getSupplier_static
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: bipush 8
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: bipush 6
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ interfaces: 0, fields: 0, methods: 1, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass."<init>":(I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass;
+ 0 6 1 x I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 4, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 17 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 9 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2."<init>":()V
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+ Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
+ 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/TinyFrameworkPackageRedirect;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/supported/UnsupportedClass
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method com/supported/UnsupportedClass."<init>":(I)V
+ x: invokevirtual #x // Method com/supported/UnsupportedClass.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 12 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
+ Compiled from "TinyFrameworkRenamedClassCaller.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller();
+ 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/TinyFrameworkRenamedClassCaller;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed."<init>":(I)V
+ x: invokevirtual #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 12 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkRenamedClassCaller.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/A.class
+ Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.A
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/A
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "A.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/sub/A.class
+ Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "A.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class
+ Compiled from "C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "C1.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class
+ Compiled from "C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "C2.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class
+ Compiled from "C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "C3.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class
+ Compiled from "CA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "CA.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class
+ Compiled from "CB.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "CB.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.class
+ Compiled from "Class_C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_C1.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.class
+ Compiled from "Class_C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_C2.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.class
+ Compiled from "Class_C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C3
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_C3.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.class
+ Compiled from "Class_I1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.I1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_I1.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.class
+ Compiled from "Class_I1_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I1,com.android.hoststubgen.test.tinyframework.subclasstest.IA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
+ super_class: #x // java/lang/Object
+ interfaces: 2, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_I1_IA.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.class
+ Compiled from "Class_I2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 implements com.android.hoststubgen.test.tinyframework.subclasstest.I2
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_I2.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.class
+ Compiled from "Class_I3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.I3
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "Class_I3.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class
+ Compiled from "I1.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "I1.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class
+ Compiled from "I2.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "I2.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class
+ Compiled from "I3.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "I3.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class
+ Compiled from "IA.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "IA.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class
+ Compiled from "IB.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "IB.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/supported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.supported.UnsupportedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/supported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 3
+ private final int mValue;
+ descriptor: I
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.supported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field mValue:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/supported/UnsupportedClass;
+ 0 10 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mValue:I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/supported/UnsupportedClass;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/unsupported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/unsupported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.unsupported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/unsupported/UnsupportedClass;
+ 0 14 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int getValue();
+ 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 This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/unsupported/UnsupportedClass;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.class
+ Compiled from "TinyFrameworkToBeRenamed.java"
+public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 3
+ private final int mValue;
+ descriptor: I
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field mValue:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 0 10 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mValue:I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkToBeRenamed.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
new file mode 100644
index 000000000000..49769e648bbf
--- /dev/null
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
@@ -0,0 +1,4896 @@
+## Class: android/hosttest/annotation/HostSideTestClassLoadHook.class
+ Compiled from "HostSideTestClassLoadHook.java"
+public interface android.hosttest.annotation.HostSideTestClassLoadHook extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 2, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestClassLoadHook
+ 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 abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestKeep.class
+ Compiled from "HostSideTestKeep.java"
+public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestKeep
+ 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
+}
+SourceFile: "HostSideTestKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRedirect.class
+ Compiled from "HostSideTestRedirect.java"
+public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestRedirect
+ 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
+}
+SourceFile: "HostSideTestRedirect.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRedirectionClass.class
+ Compiled from "HostSideTestRedirectionClass.java"
+public interface android.hosttest.annotation.HostSideTestRedirectionClass extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 2, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestRedirectionClass
+ 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 abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestRedirectionClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRemove.class
+ Compiled from "HostSideTestRemove.java"
+public interface android.hosttest.annotation.HostSideTestRemove extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRemove
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestRemove
+ 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
+}
+SourceFile: "HostSideTestRemove.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestStaticInitializerKeep.class
+ Compiled from "HostSideTestStaticInitializerKeep.java"
+public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestStaticInitializerKeep
+ 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
+}
+SourceFile: "HostSideTestStaticInitializerKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestSubstitute.class
+ Compiled from "HostSideTestSubstitute.java"
+public interface android.hosttest.annotation.HostSideTestSubstitute extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 2, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestSubstitute
+ 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 abstract java.lang.String suffix();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "HostSideTestSubstitute.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestThrow.class
+ Compiled from "HostSideTestThrow.java"
+public interface android.hosttest.annotation.HostSideTestThrow extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestThrow
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestThrow
+ 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
+}
+SourceFile: "HostSideTestThrow.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassKeep.class
+ Compiled from "HostSideTestWholeClassKeep.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestWholeClassKeep
+ 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
+}
+SourceFile: "HostSideTestWholeClassKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy.class
+ Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, 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/IPretendingAidl$Stub$Proxy
+ 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.IPretendingAidl$Stub$Proxy();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+ 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/IPretendingAidl$Stub$Proxy;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+ 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
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 a I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub.class
+ Compiled from "IPretendingAidl.java"
+public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, 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/IPretendingAidl$Stub
+ 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.IPretendingAidl$Stub();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ 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/IPretendingAidl$Stub;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int addOne(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ x: ldc #x // String addOne
+ 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
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 a I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+## Class: com/android/hoststubgen/test/tinyframework/IPretendingAidl.class
+ Compiled from "IPretendingAidl.java"
+public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, 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/IPretendingAidl
+ 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
+}
+InnerClasses:
+ public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
+ public static #x= #x of #x; // Proxy=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy of class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+SourceFile: "IPretendingAidl.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
+ com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
+## Class: com/android/hoststubgen/test/tinyframework/R$Nested.class
+ Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R$Nested
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/R$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+ public static int[] ARRAY;
+ descriptor: [I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.R$Nested();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/R$Nested
+ 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/R$Nested;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/R$Nested
+ x: ldc #x // String <clinit>
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/R$Nested
+ 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: iconst_1
+ x: newarray int
+ x: dup
+ x: iconst_0
+ x: iconst_1
+ x: iastore
+ x: putstatic #x // Field ARRAY:[I
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+SourceFile: "R.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/R
+## Class: com/android/hoststubgen/test/tinyframework/R.class
+ Compiled from "R.java"
+public class com.android.hoststubgen.test.tinyframework.R
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/R
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, 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/R
+ 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.R();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/R
+ 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/R;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
+SourceFile: "R.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/R$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class
+ Compiled from "TinyFrameworkAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 7, attributes: 3
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ 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/TinyFrameworkAnnotations
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ 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.TinyFrameworkAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+ 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: aload_0
+ x: iconst_1
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public int addOne(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/TinyFrameworkAnnotations
+ x: ldc #x // String addOne
+ 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
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ 11 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ 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/TinyFrameworkAnnotations
+ 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
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
+ 11 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+ 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
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.String unsupportedMethod();
+ 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/TinyFrameworkAnnotations
+ 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: 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: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+
+ public int toBeIgnored();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
+ x: ldc #x // String toBeIgnored
+ 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.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestIgnore
+}
+SourceFile: "TinyFrameworkAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+ Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+ descriptor: Ljava/util/Set;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/Set<Ljava/lang/Class<*>;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ 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/TinyFrameworkClassLoadHook;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static void onClassLoaded(java.lang.Class<?>);
+ descriptor: (Ljava/lang/Class;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ x: ldc #x // String onClassLoaded
+ x: ldc #x // String (Ljava/lang/Class;)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: getstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: aload_0
+ x: invokeinterface #x, 2 // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
+ x: pop
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 clazz Ljava/lang/Class;
+ LocalVariableTypeTable:
+ Start Length Slot Name Signature
+ 11 11 0 clazz Ljava/lang/Class<*>;
+ Signature: #x // (Ljava/lang/Class<*>;)V
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ x: ldc #x // String <clinit>
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ 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: new #x // class java/util/HashSet
+ x: dup
+ x: invokespecial #x // Method java/util/HashSet."<init>":()V
+ x: putstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations.class
+ Compiled from "TinyFrameworkClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAnnotations
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 5, attributes: 3
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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/TinyFrameworkClassWideAnnotations
+ 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.TinyFrameworkClassWideAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
+ 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: aload_0
+ x: iconst_1
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int addOne(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/TinyFrameworkClassWideAnnotations
+ x: ldc #x // String addOne
+ 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
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+ 11 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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/TinyFrameworkClassWideAnnotations
+ 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
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations;
+ 11 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.String unsupportedMethod();
+ 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/TinyFrameworkClassWideAnnotations
+ 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: 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: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+}
+SourceFile: "TinyFrameworkClassWideAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+ Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 0, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+ Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 1, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ x: ldc #x // String <clinit>
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: iconst_1
+ x: putstatic #x // Field sInitialized:Z
+ x: new #x // class java/lang/Object
+ x: dup
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: putstatic #x // Field sObject:Ljava/lang/Object;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+ Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+ minor version: 0
+ major version: 65
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 6, methods: 7, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private final java.lang.String mLongName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private final java.lang.String mShortName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String values
+ x: ldc #x // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ 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: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;"
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String valueOf
+ x: ldc #x // String (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 name Ljava/lang/String;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> mandated
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+ descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=4, locals=5, args_size=5
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String <init>
+ x: ldc #x // String (Ljava/lang/String;ILjava/lang/String;Ljava/lang/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: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: aload_0
+ x: aload_3
+ x: putfield #x // Field mLongName:Ljava/lang/String;
+ x: aload_0
+ x: aload 4
+ x: putfield #x // Field mShortName:Ljava/lang/String;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 18 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ 11 18 3 longName Ljava/lang/String;
+ 11 18 4 shortName Ljava/lang/String;
+ Signature: #x // (Ljava/lang/String;Ljava/lang/String;)V
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+ <no name>
+ <no name>
+
+ public java.lang.String getLongName();
+ 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/TinyFrameworkEnumComplex
+ x: ldc #x // String getLongName
+ 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: getfield #x // Field mLongName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public java.lang.String getShortName();
+ 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/TinyFrameworkEnumComplex
+ x: ldc #x // String getShortName
+ 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: getfield #x // Field mShortName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String $values
+ x: ldc #x // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ 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_3
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_2
+ x: getstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=6, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String <clinit>
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ 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: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String RED
+ x: iconst_0
+ x: ldc #x // String Red
+ x: ldc #x // String R
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String GREEN
+ x: iconst_1
+ x: ldc #x // String Green
+ x: ldc #x // String G
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String BLUE
+ x: iconst_2
+ x: ldc #x // String Blue
+ x: ldc #x // String B
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+ Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+ minor version: 0
+ major version: 65
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 3, methods: 5, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String values
+ x: ldc #x // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ 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: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;"
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String valueOf
+ x: ldc #x // String (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ 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 // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 name Ljava/lang/String;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> mandated
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+ descriptor: (Ljava/lang/String;I)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=4, locals=3, args_size=3
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String <init>
+ x: ldc #x // String (Ljava/lang/String;I)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: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 7 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ Signature: #x // ()V
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> synthetic
+ <no name> synthetic
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String $values
+ x: ldc #x // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ 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_2
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String <clinit>
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ 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: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String CAT
+ x: iconst_0
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String DOG
+ x: iconst_1
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+ Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+ 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/TinyFrameworkExceptionTester
+ 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.TinyFrameworkExceptionTester();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ 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/TinyFrameworkExceptionTester;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int testException();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ x: ldc #x // String testException
+ 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: new #x // class java/lang/IllegalStateException
+ x: dup
+ x: ldc #x // String Inner exception
+ x: invokespecial #x // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ x: astore_0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Outer exception
+ x: aload_0
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;Ljava/lang/Throwable;)V
+ x: athrow
+ Exception table:
+ from to target type
+ 11 21 21 Class java/lang/Exception
+ StackMapTable: number_of_entries = 1
+ frame_type = 85 /* same_locals_1_stack_item */
+ stack = [ class java/lang/Exception ]
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 22 11 0 e Ljava/lang/Exception;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+ Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+ minor version: 0
+ major version: 65
+ 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: 15, attributes: 2
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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/TinyFrameworkForTextPolicy
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ 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.TinyFrameworkForTextPolicy();
+ 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 <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: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int addOne(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 addOne
+ 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
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 11 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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 (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
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 11 4 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ 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 (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
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.String unsupportedMethod();
+ 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 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: 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: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 6
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ 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: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String getSupplier
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ 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: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String getSupplier_static
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ 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: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String lambda$getSupplier_static$3
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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: bipush 8
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String lambda$getSupplier$2
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String lambda$static$1
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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: bipush 6
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String lambda$new$0
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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_5
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String <clinit>
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ 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: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+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
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$static$1:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 6
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ 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: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String getSupplier
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ 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: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String getSupplier_static
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ 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: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String lambda$getSupplier_static$3
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String lambda$getSupplier$2
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String lambda$static$1
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String lambda$new$0
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String <clinit>
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ 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: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+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
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ 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 ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$static$1:()Ljava/lang/Integer;
+ #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: 65
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+}
+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.HostStubGenProcessedAsKeep
+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: 65
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+
+ 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.HostStubGenProcessedAsKeep
+}
+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.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+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
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 15, attributes: 3
+ int value;
+ descriptor: I
+ flags: (0x0000)
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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/TinyFrameworkNative
+ 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.TinyFrameworkNative();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ 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/TinyFrameworkNative;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeAddTwo
+ 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
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public static int nativeAddTwo_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeAddTwo_should_be_like_this
+ 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
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 arg I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeLongPlus
+ x: ldc #x // String (JJ)J
+ 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: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public static long nativeLongPlus_should_be_like_this(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeLongPlus_should_be_like_this
+ x: ldc #x // String (JJ)J
+ 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: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 arg1 J
+ 11 6 2 arg2 J
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public void setValue(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String setValue
+ x: ldc #x // String (I)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: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 11 6 1 v I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int nativeNonStaticAddToValue(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/TinyFrameworkNative
+ x: ldc #x // String nativeNonStaticAddToValue
+ 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
+ x: aload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public int nativeNonStaticAddToValue_should_be_like_this(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/TinyFrameworkNative
+ x: ldc #x // String nativeNonStaticAddToValue_should_be_like_this
+ 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
+ x: aload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 11 6 1 arg I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static void nativeStillNotSupported();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeStillNotSupported
+ 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: 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: athrow
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsThrow
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+
+ public static native void nativeStillKeep();
+ descriptor: ()V
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static void nativeStillNotSupported_should_be_like_this();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeStillNotSupported_should_be_like_this
+ 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: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static byte nativeBytePlus(byte, byte);
+ descriptor: (BB)B
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeBytePlus
+ x: ldc #x // String (BB)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: iload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeBytePlus:(BB)B
+ x: ireturn
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public void notNativeRedirected();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String notNativeRedirected
+ 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: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.notNativeRedirected:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+ x: return
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+
+ public static void notNativeStaticRedirected();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String notNativeStaticRedirected
+ 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: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.notNativeStaticRedirected:()V
+ x: return
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsSubstitute
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRedirect
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestRedirectionClass(
+ value="TinyFrameworkNative_host"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.class
+ Compiled from "TinyFrameworkNative_host.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 8, attributes: 3
+ 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/TinyFrameworkNative_host
+ 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.TinyFrameworkNative_host();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ 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/TinyFrameworkNative_host;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeAddTwo
+ 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
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 arg I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeLongPlus
+ x: ldc #x // String (JJ)J
+ 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: lload_0
+ x: lload_2
+ x: ladd
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 arg1 J
+ 11 4 2 arg2 J
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int nativeNonStaticAddToValue(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative, int);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeNonStaticAddToValue
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;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
+ x: aload_0
+ x: getfield #x // Field com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.value:I
+ x: iload_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 7 0 source Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 11 7 1 arg I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static byte nativeBytePlus(byte, byte);
+ descriptor: (BB)B
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeBytePlus
+ x: ldc #x // String (BB)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: iload_0
+ x: iload_1
+ x: iadd
+ x: i2b
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 arg1 B
+ 11 5 1 arg2 B
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static void notNativeRedirected(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String notNativeRedirected
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;)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
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 1 0 source Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static void notNativeStaticRedirected();
+ descriptor: ()V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String notNativeStaticRedirected
+ 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
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkNative_host.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, 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/TinyFrameworkNestedClasses$1
+ 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
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String <init>
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)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/TinyFrameworkNestedClasses$1;
+ 11 5 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ 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 get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, 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/TinyFrameworkNestedClasses$2
+ 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
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ 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/TinyFrameworkNestedClasses$2;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ 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 get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, 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/TinyFrameworkNestedClasses$3
+ 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
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String <init>
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)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/TinyFrameworkNestedClasses$3;
+ 11 5 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ 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 get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, 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/TinyFrameworkNestedClasses$4
+ 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
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ 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/TinyFrameworkNestedClasses$4;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ 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 get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier_static
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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/TinyFrameworkNestedClasses$BaseClass
+ 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.TinyFrameworkNestedClasses$BaseClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)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: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass;
+ 11 10 1 x I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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/TinyFrameworkNestedClasses$InnerClass
+ 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.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)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: aload_0
+ x: iconst_5
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
+ 11 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ MethodParameters:
+ Name Flags
+ <no name> final mandated
+}
+InnerClasses:
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 65
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, 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/TinyFrameworkNestedClasses$StaticNestedClass$1
+ 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
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ 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/TinyFrameworkNestedClasses$StaticNestedClass$1;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ 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: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ 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 get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass.getSupplier_static
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ 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.TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ 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: aload_0
+ x: bipush 8
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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/TinyFrameworkNestedClasses$StaticNestedClass
+ 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.TinyFrameworkNestedClasses$StaticNestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ 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: aload_0
+ x: bipush 6
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ x: ldc #x // String getSupplier_static
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ 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 com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ interfaces: 0, fields: 0, methods: 2, 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/TinyFrameworkNestedClasses$SubClass
+ 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.TinyFrameworkNestedClasses$SubClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)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: iload_1
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass."<init>":(I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass;
+ 11 6 1 x I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 4, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ 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: aload_0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 17 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String getSupplier
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ 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 com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 9 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String getSupplier_static
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ 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 com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String <clinit>
+ 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: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ 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: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2."<init>":()V
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // Double$NestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+ Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+ 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/TinyFrameworkPackageRedirect
+ 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.TinyFrameworkPackageRedirect();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ 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/TinyFrameworkPackageRedirect;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ x: ldc #x // String foo
+ 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
+ x: new #x // class com/supported/UnsupportedClass
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method com/supported/UnsupportedClass."<init>":(I)V
+ x: invokevirtual #x // Method com/supported/UnsupportedClass.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 12 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
+ Compiled from "TinyFrameworkRenamedClassCaller.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+ 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/TinyFrameworkRenamedClassCaller
+ 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.TinyFrameworkRenamedClassCaller();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+ 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/TinyFrameworkRenamedClassCaller;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+ x: ldc #x // String foo
+ 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
+ x: new #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed."<init>":(I)V
+ x: invokevirtual #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 12 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkRenamedClassCaller.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/A.class
+ Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.A
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/A
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/packagetest/A
+ 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
+}
+SourceFile: "A.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/packagetest/sub/A.class
+ Compiled from "A.java"
+public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/packagetest/sub/A
+ 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
+}
+SourceFile: "A.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C1.class
+ Compiled from "C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/C1
+ 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
+}
+SourceFile: "C1.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C2.class
+ Compiled from "C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/C2
+ 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
+}
+SourceFile: "C2.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/C3.class
+ Compiled from "C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/C3
+ 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
+}
+SourceFile: "C3.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CA.class
+ Compiled from "CA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/CA
+ 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
+}
+SourceFile: "CA.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/CB.class
+ Compiled from "CB.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/CB
+ 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
+}
+SourceFile: "CB.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1.class
+ Compiled from "Class_C1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 extends com.android.hoststubgen.test.tinyframework.subclasstest.C1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/Class_C1
+ 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
+}
+SourceFile: "Class_C1.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2.class
+ Compiled from "Class_C2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 extends com.android.hoststubgen.test.tinyframework.subclasstest.C2
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/Class_C2
+ 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
+}
+SourceFile: "Class_C2.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3.class
+ Compiled from "Class_C3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 extends com.android.hoststubgen.test.tinyframework.subclasstest.C3
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
+ super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/Class_C3
+ 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
+}
+SourceFile: "Class_C3.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1.class
+ Compiled from "Class_I1.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 implements com.android.hoststubgen.test.tinyframework.subclasstest.I1
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/Class_I1
+ 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
+}
+SourceFile: "Class_I1.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA.class
+ Compiled from "Class_I1_IA.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA implements com.android.hoststubgen.test.tinyframework.subclasstest.I1,com.android.hoststubgen.test.tinyframework.subclasstest.IA
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
+ super_class: #x // java/lang/Object
+ interfaces: 2, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/Class_I1_IA
+ 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
+}
+SourceFile: "Class_I1_IA.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2.class
+ Compiled from "Class_I2.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 implements com.android.hoststubgen.test.tinyframework.subclasstest.I2
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/Class_I2
+ 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
+}
+SourceFile: "Class_I2.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3.class
+ Compiled from "Class_I3.java"
+public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 implements com.android.hoststubgen.test.tinyframework.subclasstest.I3
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/Class_I3
+ 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
+}
+SourceFile: "Class_I3.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I1.class
+ Compiled from "I1.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/I1
+ 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
+}
+SourceFile: "I1.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class
+ Compiled from "I2.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 extends com.android.hoststubgen.test.tinyframework.subclasstest.I1
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/I2
+ 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
+}
+SourceFile: "I2.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class
+ Compiled from "I3.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 extends com.android.hoststubgen.test.tinyframework.subclasstest.I2
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/I3
+ 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
+}
+SourceFile: "I3.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class
+ Compiled from "IA.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/IA
+ 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
+}
+SourceFile: "IA.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class
+ Compiled from "IB.java"
+public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
+ minor version: 0
+ major version: 65
+ flags: (0x0601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
+ this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 2
+ 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/subclasstest/IB
+ 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
+}
+SourceFile: "IB.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+## Class: com/supported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.supported.UnsupportedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/supported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ private final int mValue;
+ descriptor: I
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/supported/UnsupportedClass
+ 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.supported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/supported/UnsupportedClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)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: aload_0
+ x: iload_1
+ x: putfield #x // Field mValue:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/supported/UnsupportedClass;
+ 11 10 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/supported/UnsupportedClass
+ x: ldc #x // String getValue
+ 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: aload_0
+ x: getfield #x // Field mValue:I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/supported/UnsupportedClass;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/unsupported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/unsupported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/unsupported/UnsupportedClass
+ 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.unsupported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/unsupported/UnsupportedClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)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: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 14 0 this Lcom/unsupported/UnsupportedClass;
+ 11 14 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/unsupported/UnsupportedClass
+ x: ldc #x // String getValue
+ 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: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/unsupported/UnsupportedClass;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.class
+ Compiled from "TinyFrameworkToBeRenamed.java"
+public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ private final int mValue;
+ descriptor: I
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ 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/TinyFrameworkToBeRenamed
+ 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 rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)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: aload_0
+ x: iload_1
+ x: putfield #x // Field mValue:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 11 10 1 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: ldc #x // String getValue
+ 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: aload_0
+ x: getfield #x // Field mValue:I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+SourceFile: "TinyFrameworkToBeRenamed.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
index 7a7de3553829..88fa492addb8 100755
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
@@ -20,18 +20,23 @@ import os
import unittest
import subprocess
-GOLDEN_DIR = 'golden-output'
+GOLDEN_DIRS = [
+ 'golden-output',
+ 'golden-output.RELEASE_TARGET_JAVA_21',
+]
+
# Run diff.
def run_diff(file1, file2):
- command = ['diff', '-u', '--ignore-blank-lines', '--ignore-space-change', file1, file2]
+ command = ['diff', '-u', '--ignore-blank-lines',
+ '--ignore-space-change', file1, file2]
print(' '.join(command))
- result = subprocess.run(command, stderr = sys.stdout)
+ result = subprocess.run(command, stderr=sys.stdout)
success = result.returncode == 0
if success:
- print(f'No diff found.')
+ print('No diff found.')
else:
print(f'Fail: {file1} and {file2} are different.')
@@ -39,27 +44,42 @@ def run_diff(file1, file2):
# Check one golden file.
-def check_one_file(filename):
+def check_one_file(golden_dir, filename):
print(f'= Checking file: {filename}')
- return run_diff(os.path.join(GOLDEN_DIR, filename), filename)
+ return run_diff(os.path.join(golden_dir, filename), filename)
+
class TestWithGoldenOutput(unittest.TestCase):
# Test to check the generated jar files to the golden output.
+ # Depending on build flags, the golden output may differ in expected ways.
+ # So only expect the files to match one of the possible golden outputs.
def test_compare_to_golden(self):
- self.skipTest("test cannot handle multiple images (see b/378470825)")
- files = os.listdir(GOLDEN_DIR)
+ success = False
+
+ for golden_dir in GOLDEN_DIRS:
+ if self.matches_golden(golden_dir):
+ success = True
+ print(f"Test passes for dir: {golden_dir}")
+ break
+
+ if not success:
+ self.fail('Some files are different. ' +
+ 'See stdout log for more details.')
+
+ def matches_golden(self, golden_dir):
+ files = os.listdir(golden_dir)
files.sort()
- print(f"Golden files: {files}")
- success = True
+ print(f"Golden files for {golden_dir}: {files}")
+ match_success = True
for file in files:
- if not check_one_file(file):
- success = False
+ if not check_one_file(golden_dir, file):
+ match_success = False
+
+ return match_success
- if not success:
- self.fail('Some files are different. See stdout log for more details.')
if __name__ == "__main__":
unittest.main(verbosity=2)
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index 2808056f72c9..a0b989b44f4f 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -55,16 +55,6 @@ flag {
}
flag {
- name: "compute_window_changes_on_a11y_v2"
- namespace: "accessibility"
- description: "Computes accessibility window changes in accessibility instead of wm package."
- bug: "322444245"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "deprecate_package_list_observer"
namespace: "accessibility"
description: "Stops using the deprecated PackageListObserver."
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 9a81aa6cc506..5cbe0c4fe4d2 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -433,22 +433,10 @@ public class AccessibilityWindowManager {
return Collections.emptyList();
}
- /**
- * Callbacks from window manager when there's an accessibility change in windows.
- *
- * @param forceSend Send the windows for accessibility even if they haven't changed.
- * @param topFocusedDisplayId The display Id which has the top focused window.
- * @param topFocusedWindowToken The window token of top focused window.
- * @param windows The windows for accessibility.
- */
- @Override
- public void onWindowsForAccessibilityChanged(boolean forceSend, int topFocusedDisplayId,
+ private void onWindowsForAccessibilityChanged(boolean forceSend, int topFocusedDisplayId,
IBinder topFocusedWindowToken, @NonNull List<WindowInfo> windows) {
+ // TODO(b/322444245): no longer need to get a lock.
synchronized (mLock) {
- if (!Flags.computeWindowChangesOnA11yV2()) {
- // If the flag is enabled, it's already done in #createWindowInfoListLocked.
- updateWindowsByWindowAttributesLocked(windows);
- }
if (DEBUG) {
Slogf.i(LOG_TAG, "mDisplayId=%d, topFocusedDisplayId=%d, currentUserId=%d, "
+ "visibleBgUsers=%s", mDisplayId, topFocusedDisplayId,
@@ -490,9 +478,7 @@ public class AccessibilityWindowManager {
}
/**
- * Called when the windows for accessibility changed. This is called if
- * {@link com.android.server.accessibility.Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2} is
- * true.
+ * Called when the windows for accessibility changed.
*
* @param forceSend Send the windows for accessibility even if they haven't
* changed.
@@ -655,16 +641,6 @@ public class AccessibilityWindowManager {
return true;
}
- private void updateWindowsByWindowAttributesLocked(List<WindowInfo> windows) {
- for (int i = windows.size() - 1; i >= 0; i--) {
- final WindowInfo windowInfo = windows.get(i);
- final IBinder token = windowInfo.token;
- final int windowId = findWindowIdLocked(
- mAccessibilityUserManager.getCurrentUserIdLocked(), token);
- updateWindowWithWindowAttributes(windowInfo, mWindowAttributes.get(windowId));
- }
- }
-
private void updateWindowWithWindowAttributes(@NonNull WindowInfo windowInfo,
@Nullable AccessibilityWindowAttributes attributes) {
if (attributes == null) {
@@ -990,19 +966,6 @@ public class AccessibilityWindowManager {
private AccessibilityWindowInfo populateReportedWindowLocked(int userId,
WindowInfo window, SparseArray<AccessibilityWindowInfo> oldWindowsById) {
final int windowId = findWindowIdLocked(userId, window.token);
-
- // With the flag enabled, createWindowInfoListLocked() already removes invalid windows.
- if (!Flags.computeWindowChangesOnA11yV2()) {
- if (windowId < 0) {
- return null;
- }
-
- // Don't need to add the embedded hierarchy windows into the a11y windows list.
- if (isEmbeddedHierarchyWindowsLocked(windowId)) {
- return null;
- }
- }
-
final AccessibilityWindowInfo reportedWindow = AccessibilityWindowInfo.obtain();
reportedWindow.setId(windowId);
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 8b5b93e96494..d4beb019e049 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -44,7 +44,6 @@ import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.app.compat.CompatChanges;
import android.companion.AssociationInfo;
-import android.companion.AssociationRequest;
import android.companion.virtual.ActivityPolicyExemption;
import android.companion.virtual.IVirtualDevice;
import android.companion.virtual.IVirtualDeviceActivityListener;
@@ -156,9 +155,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
private static final String PERSISTENT_ID_PREFIX_CDM_ASSOCIATION = "companion:";
- private static final List<String> DEVICE_PROFILES_ALLOWING_MIRROR_DISPLAYS = List.of(
- AssociationRequest.DEVICE_PROFILE_APP_STREAMING);
-
/**
* Timeout until {@link #launchPendingIntent} stops waiting for an activity to be launched.
*/
@@ -1352,11 +1348,6 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
return hasCustomAudioInputSupportInternal();
}
- @Override
- public boolean canCreateMirrorDisplays() {
- return DEVICE_PROFILES_ALLOWING_MIRROR_DISPLAYS.contains(getDeviceProfile());
- }
-
private boolean hasCustomAudioInputSupportInternal() {
if (!Flags.vdmPublicApis()) {
return false;
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index 485bf31dfb64..aabbd3bf49ae 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -65,6 +65,7 @@ import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -347,7 +348,8 @@ public class BinaryTransparencyService extends SystemService {
+ " packages after considering preloads");
}
- if (CompatChanges.isChangeEnabled(LOG_MBA_INFO)) {
+ if (!android.app.Flags.backgroundInstallControlCallbackApi()
+ && CompatChanges.isChangeEnabled(LOG_MBA_INFO)) {
// lastly measure all newly installed MBAs
List<IBinaryTransparencyService.AppInfo> allMbaInfo =
collectAllSilentInstalledMbaInfo(packagesMeasured);
@@ -1158,6 +1160,49 @@ public class BinaryTransparencyService extends SystemService {
}
/**
+ * Receive callbacks from BIC to write silently installed apps to log
+ *
+ * TODO: Add a host test for testing registration and callback of BicCallbackHandler
+ * b/380002484
+ */
+ static class BicCallbackHandler extends IRemoteCallback.Stub {
+ private static final String BIC_CALLBACK_HANDLER_TAG =
+ "BTS.BicCallbackHandler";
+ private final BinaryTransparencyServiceImpl mServiceImpl;
+ static final String FLAGGED_PACKAGE_NAME_KEY = "packageName";
+
+ BicCallbackHandler(BinaryTransparencyServiceImpl impl) {
+ mServiceImpl = impl;
+ }
+
+ @Override
+ public void sendResult(Bundle data) {
+ String packageName = data.getString(FLAGGED_PACKAGE_NAME_KEY);
+ if (packageName == null) return;
+ if (DEBUG) {
+ Slog.d(BIC_CALLBACK_HANDLER_TAG, "background install event detected for "
+ + packageName);
+ }
+
+ PackageState packageState = LocalServices.getService(PackageManagerInternal.class)
+ .getPackageStateInternal(packageName);
+ if (packageState == null) {
+ Slog.w(TAG, "Package state is unavailable, ignoring the package "
+ + packageName);
+ return;
+ }
+ if (packageState.isUpdatedSystemApp()) {
+ return;
+ }
+ List<IBinaryTransparencyService.AppInfo> mbaInfo = mServiceImpl.collectAppInfo(
+ packageState, MBA_STATUS_NEW_INSTALL);
+ for (IBinaryTransparencyService.AppInfo appInfo : mbaInfo) {
+ mServiceImpl.writeAppInfoToLog(appInfo);
+ }
+ }
+ };
+
+ /**
* Called when the system service should publish a binder service using
* {@link #publishBinderService(String, IBinder).}
*/
@@ -1534,6 +1579,19 @@ public class BinaryTransparencyService extends SystemService {
}
}
+ private void registerBicCallback() {
+ IBackgroundInstallControlService iBics =
+ IBackgroundInstallControlService.Stub.asInterface(
+ ServiceManager.getService(
+ Context.BACKGROUND_INSTALL_CONTROL_SERVICE));
+ try {
+ iBics.registerBackgroundInstallCallback(
+ new BicCallbackHandler(mServiceImpl));
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to register BackgroundInstallControl callback.");
+ }
+ }
+
private boolean isPackagePreloaded(String packageName) {
PackageManager pm = mContext.getPackageManager();
try {
@@ -1596,6 +1654,10 @@ public class BinaryTransparencyService extends SystemService {
private void registerAllPackageUpdateObservers() {
registerApkAndNonStagedApexUpdateListener();
registerStagedApexUpdateObserver();
+ if (android.app.Flags.backgroundInstallControlCallbackApi()
+ && CompatChanges.isChangeEnabled(LOG_MBA_INFO)) {
+ registerBicCallback();
+ }
}
private String translateContentDigestAlgorithmIdToString(int algorithmId) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index ab3ab159ba12..71cbc10074d6 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -9319,6 +9319,46 @@ public final class ActiveServices {
Slog.e(TAG, "stopForegroundServiceDelegateLocked delegate does not exist");
}
}
+ /**
+ * Handles notifications from MediaSessionService about active media service.
+ * This method evaluates the provided information and transitions corresponding service to
+ * foreground state.
+ *
+ * @param packageName The package name of the app running the service.
+ * @param userId The user ID associated with the service.
+ * @param notificationId The ID of the media notification associated with the service.
+ */
+ void notifyActiveMediaForegroundServiceLocked(@NonNull String packageName,
+ @UserIdInt int userId, int notificationId) {
+ if (!enableNotifyingActivityManagerWithMediaSessionStatusChange()) {
+ return;
+ }
+
+ final ServiceMap smap = mServiceMap.get(userId);
+ if (smap == null) {
+ return;
+ }
+ final int serviceSize = smap.mServicesByInstanceName.size();
+ for (int i = 0; i < serviceSize; i++) {
+ final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i);
+ if (sr.appInfo.packageName.equals(packageName) && !sr.isForeground) {
+ // foregroundServiceType is cleared when media session is user-disengaged
+ // and calls notifyInactiveMediaForegroundService->setServiceForegroundInnerLocked.
+ if (sr.foregroundServiceType
+ == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE
+ && sr.foregroundId == notificationId) {
+ if (DEBUG_FOREGROUND_SERVICE) {
+ Slog.d(TAG, "Moving media service to foreground for package "
+ + packageName);
+ }
+ setServiceForegroundInnerLocked(sr, sr.foregroundId,
+ sr.foregroundNoti, /* flags */ 0,
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK,
+ /* callingUidStart */ 0);
+ }
+ }
+ }
+ }
/**
* Handles notifications from MediaSessionService about inactive media foreground services.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5c5361bacf5a..d79e66db8661 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17923,6 +17923,15 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public void notifyActiveMediaForegroundService(@NonNull String packageName,
+ @UserIdInt int userId, int notificationId) {
+ synchronized (ActivityManagerService.this) {
+ mServices.notifyActiveMediaForegroundServiceLocked(packageName, userId,
+ notificationId);
+ }
+ }
+
+ @Override
public void notifyInactiveMediaForegroundService(@NonNull String packageName,
@UserIdInt int userId, int notificationId) {
synchronized (ActivityManagerService.this) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index d3d3fc968ae6..fa40283d43e1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -471,14 +471,14 @@ final class ActivityManagerShellCommand extends ShellCommand {
}
int userId = UserHandle.USER_CURRENT;
final String cmd = getNextArgRequired();
- if ("inactive".equals(cmd)) {
+ if ("inactive".equals(cmd) || "active".equals(cmd)) {
String opt;
while ((opt = getNextOption()) != null) {
if (opt.equals("--user")) {
userId = UserHandle.parseUserArg(getNextArgRequired());
if (userId == UserHandle.USER_ALL) {
err.println(
- "Error: Can't set media fgs inactive with user 'all'");
+ "Error: Can't set media fgs with user 'all'");
return -1;
}
} else {
@@ -492,8 +492,13 @@ final class ActivityManagerShellCommand extends ShellCommand {
err.println("Error: notification id cannot be zero");
return -1;
}
- mInternal.mInternal.notifyInactiveMediaForegroundService(pkgName,
- userId, notificationId);
+ if ("inactive".equals(cmd)) {
+ mInternal.mInternal.notifyInactiveMediaForegroundService(pkgName,
+ userId, notificationId);
+ } else {
+ mInternal.mInternal.notifyActiveMediaForegroundService(pkgName,
+ userId, notificationId);
+ }
return 0;
}
err.println("Error: Unknown set-media-foreground-service command: " + cmd);
@@ -4683,9 +4688,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
pw.println(" --protobuf: format output using protobuffer");
pw.println(" set-app-zygote-preload-timeout <TIMEOUT_IN_MS>");
pw.println(" Set the timeout for preloading code in the app-zygote");
- pw.println(" set-media-foreground-service inactive [--user USER_ID]"
- + " <PACKAGE> <NOTIFICATION_ID>");
- pw.println(" Set an app's media foreground service inactive.");
+ pw.println(" set-media-foreground-service inactive|active [--user USER_ID] <PACKAGE>"
+ + " <NOTIFICATION_ID>");
+ pw.println(" Set an app's media service inactive or active.");
Intent.printIntentArgsHelp(pw, "");
}
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 415f78aa3ee5..b7a5f3e4099a 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -598,7 +598,7 @@ class AppErrors {
}
if (r != null) {
- mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode(),
+ mPackageWatchdog.notifyPackageFailure(r.getPackageListWithVersionCode(),
PackageWatchdog.FAILURE_REASON_APP_CRASH);
synchronized (mService) {
@@ -1142,7 +1142,7 @@ class AppErrors {
}
// Notify PackageWatchdog without the lock held
if (packageList != null) {
- mPackageWatchdog.onPackageFailure(packageList,
+ mPackageWatchdog.notifyPackageFailure(packageList,
PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING);
}
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 2eb9f3cb600f..d5bd05764f38 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -1262,6 +1262,17 @@ public final class BatteryStatsService extends IBatteryStats.Stub
mFrameworkStatsLogger = frameworkStatsLogger;
}
+ private static float clampPowerMah(double powerMah, String consumer) {
+ float resultPowerMah = 0;
+ if (powerMah <= Float.MAX_VALUE && powerMah >= Float.MIN_VALUE) {
+ resultPowerMah = (float) powerMah;
+ } else {
+ // Handle overflow appropriately
+ Slog.wtfStack(TAG, consumer + " reported powerMah float overflow: " + powerMah);
+ }
+ return resultPowerMah;
+ }
+
/**
* Generates StatsEvents for the supplied battery usage stats and adds them to
* the supplied list.
@@ -1282,7 +1293,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub
bus.getAggregateBatteryConsumer(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
- final float totalDeviceConsumedPowerMah = (float) deviceConsumer.getConsumedPower();
+ final float totalDeviceConsumedPowerMah =
+ clampPowerMah(deviceConsumer.getConsumedPower(), "AggregateBatteryConsumer");
for (@BatteryConsumer.PowerComponentId int powerComponentId :
deviceConsumer.getPowerComponentIds()) {
@@ -1314,7 +1326,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub
// Log single atom for BatteryUsageStats per uid/process_state/component/etc.
for (UidBatteryConsumer uidConsumer : uidConsumers) {
final int uid = uidConsumer.getUid();
- final float totalConsumedPowerMah = (float) uidConsumer.getConsumedPower();
+
+ final float totalConsumedPowerMah =
+ clampPowerMah(uidConsumer.getConsumedPower(), "uidConsumer-" + uid);
for (@BatteryConsumer.PowerComponentId int powerComponentId :
uidConsumer.getPowerComponentIds()) {
@@ -1358,7 +1372,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
final String powerComponentName = batteryConsumer.getPowerComponentName(componentId);
- final float powerMah = (float) batteryConsumer.getConsumedPower(key);
+ final double consumedPowerMah = batteryConsumer.getConsumedPower(key);
+ float powerMah =
+ clampPowerMah(
+ consumedPowerMah, "uidConsumer-" + uid + "-" + powerComponentName);
final long powerComponentDurationMillis = batteryConsumer.getUsageDurationMillis(key);
if (powerMah == 0 && powerComponentDurationMillis == 0) {
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index ab7cd5f29660..1a6051b6ac9c 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -66,6 +66,9 @@ per-file CarUserSwitchingDialog.java = file:platform/packages/services/Car:/OWNE
# Activity Security
per-file ActivityManager* = file:/ACTIVITY_SECURITY_OWNERS
+# Aconfig Flags
+per-file flags.aconfig = yamasani@google.com, bills@google.com, nalini@google.com
+
# Londoners
michaelwr@google.com #{LAST_RESORT_SUGGESTION}
narayan@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index b84bf6b90711..f42641ece09b 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1376,9 +1376,11 @@ public class OomAdjuster {
ProcessRecord app = lruList.get(i);
final ProcessStateRecord state = app.mState;
if (!app.isKilledByAm() && app.getThread() != null) {
- // We don't need to apply the update for the process which didn't get computed
- if (state.getCompletedAdjSeq() == mAdjSeq) {
- applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true);
+ if (!Flags.fixApplyOomadjOrder()) {
+ // We don't need to apply the update for the process which didn't get computed
+ if (state.getCompletedAdjSeq() == mAdjSeq) {
+ applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true);
+ }
}
if (app.isPendingFinishAttach()) {
@@ -1480,6 +1482,19 @@ public class OomAdjuster {
}
}
+ if (Flags.fixApplyOomadjOrder()) {
+ // We need to apply the update starting from the least recently used.
+ // Otherwise, they won't be in the correct LRU order in LMKD.
+ for (int i = 0; i < numLru; i++) {
+ ProcessRecord app = lruList.get(i);
+ // We don't need to apply the update for the process which didn't get computed
+ if (!app.isKilledByAm() && app.getThread() != null
+ && app.mState.getCompletedAdjSeq() == mAdjSeq) {
+ applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true);
+ }
+ }
+ }
+
if (!mProcsToOomAdj.isEmpty()) {
mInjector.batchSetOomAdj(mProcsToOomAdj);
mProcsToOomAdj.clear();
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 78c4f74f3afa..f28f3e1e4fdf 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -140,6 +140,7 @@ public class SettingsToPropertiesMapper {
// The list is sorted.
@VisibleForTesting
static final String[] sDeviceConfigAconfigScopes = new String[] {
+ "aaos_power_triage",
"aaos_sdv",
"accessibility",
"android_core_networking",
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index 6d247d227774..89e4a8d82676 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -245,6 +245,14 @@ flag {
}
flag {
+ name: "fix_apply_oomadj_order"
+ namespace: "backstage_power"
+ is_fixed_read_only: true
+ description: "Fix the iteration direction of process LRU list when applying oom adj"
+ bug: "378580264"
+}
+
+flag {
name: "phantom_processes_fix"
namespace: "backstage_power"
description: "Make sure setProcessGroupForPhantomProcessOfApp deals with phantom processes properly"
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 8c5152fdb0d6..6f8dc105850d 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -100,6 +100,7 @@ import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.SystemService.TargetUser;
+import com.android.server.utils.LazyJniRegistrar;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.CompatScaleProvider;
@@ -158,6 +159,10 @@ public final class GameManagerService extends IGameManagerService.Stub {
private static final String GAME_MODE_INTERVENTION_LIST_FILE_NAME =
"game_mode_intervention.list";
+ static {
+ LazyJniRegistrar.registerGameManagerService();
+ }
+
private final Context mContext;
private final Object mLock = new Object();
private final Object mDeviceConfigLock = new Object();
diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
index ed41f2e881f8..fa2e674d37c7 100644
--- a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
@@ -31,7 +31,6 @@ import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
-import static android.app.AppOpsManager.OP_TAKE_AUDIO_FOCUS;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED;
import static android.app.AppOpsManager.UID_STATE_NONEXISTENT;
@@ -177,8 +176,6 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker {
case OP_RECORD_AUDIO:
case OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO:
return PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
- case OP_TAKE_AUDIO_FOCUS:
- return PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL;
default:
return PROCESS_CAPABILITY_NONE;
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 40d5f86f8094..5c2eb5cf1086 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4954,6 +4954,15 @@ public class AudioService extends IAudioService.Stub
}
final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
+
+ final Set<Integer> a2dpDevices = AudioSystem.intersectionAudioDeviceTypes(
+ AudioSystem.DEVICE_OUT_ALL_A2DP_SET, deviceTypes);
+ if (!a2dpDevices.isEmpty()) {
+ int index = getStreamVolume(streamType,
+ a2dpDevices.toArray(new Integer[0])[0].intValue());
+ mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index);
+ }
+
final Set<Integer> absVolumeMultiModeCaseDevices =
AudioSystem.intersectionAudioDeviceTypes(
mAbsVolumeMultiModeCaseDevices, deviceTypes);
@@ -11425,6 +11434,10 @@ public class AudioService extends IAudioService.Stub
return mSpatializerHelper.canBeSpatialized(attributes, format);
}
+ public @NonNull List<Integer> getSpatializedChannelMasks() {
+ return mSpatializerHelper.getSpatializedChannelMasks();
+ }
+
/** @see Spatializer.SpatializerInfoDispatcherStub */
public void registerSpatializerCallback(
@NonNull ISpatializerCallback cb) {
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index a62ac82f27eb..a2200c9f8bf5 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -24,6 +24,7 @@ import static android.media.AudioPlaybackConfiguration.MUTED_BY_PORT_VOLUME;
import static android.media.AudioPlaybackConfiguration.MUTED_BY_STREAM_MUTED;
import static android.media.AudioPlaybackConfiguration.MUTED_BY_STREAM_VOLUME;
import static android.media.AudioPlaybackConfiguration.MUTED_BY_VOLUME_SHAPER;
+import static android.media.AudioPlaybackConfiguration.MUTED_BY_OP_CONTROL_AUDIO;
import static android.media.AudioPlaybackConfiguration.PLAYER_PIID_INVALID;
import static android.media.AudioPlaybackConfiguration.PLAYER_UPDATE_MUTED;
@@ -1388,6 +1389,10 @@ public final class PlaybackActivityMonitor
if ((eventValue & MUTED_BY_PORT_VOLUME) != 0) {
builder.append("portVolume ");
}
+ if ((eventValue & MUTED_BY_OP_CONTROL_AUDIO) != 0) {
+ builder.append("opControlAudio ");
+ }
+
}
return builder.toString();
default:
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 9265ff2d9b2d..afa90d5869e3 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -59,6 +59,8 @@ import com.android.server.utils.EventLogger;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
@@ -1100,6 +1102,23 @@ public class SpatializerHelper {
return able;
}
+ synchronized @NonNull List<Integer> getSpatializedChannelMasks() {
+ if (!checkSpatializer("getSpatializedChannelMasks")) {
+ return Collections.emptyList();
+ }
+ try {
+ final int[] nativeMasks = new int[0]; // FIXME mSpat query goes here
+ for (int i = 0; i < nativeMasks.length; i++) {
+ nativeMasks[i] = AudioFormat.convertNativeChannelMaskToOutMask(nativeMasks[i]);
+ }
+ final List<Integer> masks = Arrays.stream(nativeMasks).boxed().toList();
+ return masks;
+ } catch (Exception e) { // just catch Exception in case nativeMasks is null
+ Log.e(TAG, "Error calling getSpatializedChannelMasks", e);
+ return Collections.emptyList();
+ }
+ }
+
//------------------------------------------------------
// head tracking
final RemoteCallbackList<ISpatializerHeadTrackingModeCallback> mHeadTrackingModeCallbacks =
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 97a88542f0a4..b365ef7ff61c 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -434,21 +434,12 @@ public class BiometricService extends SystemService {
public boolean getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(int userId) {
if (!mMandatoryBiometricsEnabled.containsKey(userId)) {
- Slog.d(TAG, "update mb toggle for user " + userId);
updateMandatoryBiometricsForAllProfiles(userId);
}
if (!mMandatoryBiometricsRequirementsSatisfied.containsKey(userId)) {
- Slog.d(TAG, "update mb reqs for user " + userId);
updateMandatoryBiometricsRequirementsForAllProfiles(userId);
}
- Slog.d(TAG, mMandatoryBiometricsEnabled.getOrDefault(userId,
- DEFAULT_MANDATORY_BIOMETRICS_STATUS)
- + " " + mMandatoryBiometricsRequirementsSatisfied.getOrDefault(userId,
- DEFAULT_MANDATORY_BIOMETRICS_REQUIREMENTS_SATISFIED_STATUS)
- + " " + getEnabledForApps(userId)
- + " " + (mFingerprintEnrolledForUser.getOrDefault(userId, false /* default */)
- || mFaceEnrolledForUser.getOrDefault(userId, false /* default */)));
return mMandatoryBiometricsEnabled.getOrDefault(userId,
DEFAULT_MANDATORY_BIOMETRICS_STATUS)
&& mMandatoryBiometricsRequirementsSatisfied.getOrDefault(userId,
diff --git a/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java b/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java
index eed2bddb0312..958ab8ee0b6a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java
+++ b/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java
@@ -18,6 +18,8 @@ package com.android.server.biometrics.sensors;
import android.util.SparseArray;
+import java.util.concurrent.ConcurrentHashMap;
+
/**
* Tracks biometric performance across sensors and users.
*/
@@ -25,17 +27,12 @@ public class PerformanceTracker {
private static final String TAG = "PerformanceTracker";
// Keyed by SensorId
- private static SparseArray<PerformanceTracker> sTrackers;
+ private static final ConcurrentHashMap<Integer, PerformanceTracker> sTrackers =
+ new ConcurrentHashMap<>();
public static PerformanceTracker getInstanceForSensorId(int sensorId) {
- if (sTrackers == null) {
- sTrackers = new SparseArray<>();
- }
-
- if (!sTrackers.contains(sensorId)) {
- sTrackers.put(sensorId, new PerformanceTracker());
- }
- return sTrackers.get(sensorId);
+ PerformanceTracker tracker = sTrackers.putIfAbsent(sensorId, new PerformanceTracker());
+ return tracker != null ? tracker : sTrackers.get(sensorId);
}
private static class Info {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 36e4a7e6a7ef..944e85cc970e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -851,13 +851,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
for (int i = 0; i < mFaceSensors.size(); i++) {
final Sensor sensor = mFaceSensors.valueAt(i);
final int sensorId = mFaceSensors.keyAt(i);
- final PerformanceTracker performanceTracker = PerformanceTracker.getInstanceForSensorId(
- sensorId);
- if (performanceTracker != null) {
- performanceTracker.incrementHALDeathCount();
- } else {
- Slog.w(getTag(), "Performance tracker is null. Not counting HAL death.");
- }
+ PerformanceTracker.getInstanceForSensorId(sensorId)
+ .incrementHALDeathCount();
sensor.onBinderDied();
}
});
diff --git a/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java b/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java
index 8e725465ddd6..eef2b15c3387 100644
--- a/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java
+++ b/services/core/java/com/android/server/crashrecovery/CrashRecoveryHelper.java
@@ -93,7 +93,8 @@ public final class CrashRecoveryHelper {
return;
}
final List<VersionedPackage> pkgList = Collections.singletonList(pkg);
- PackageWatchdog.getInstance(mContext).onPackageFailure(pkgList, PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
+ PackageWatchdog.getInstance(mContext).notifyPackageFailure(pkgList,
+ PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
});
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index d2c044fdbb5e..1c1bdad01034 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -311,6 +311,11 @@ final class DisplayDeviceInfo {
*/
public FrameRateCategoryRate frameRateCategoryRate;
/**
+ * All the refresh rates supported for the default display mode.
+ */
+ public float[] supportedRefreshRates = new float[0];
+
+ /**
* The default mode of the display.
*/
public int defaultModeId;
@@ -562,7 +567,8 @@ final class DisplayDeviceInfo {
|| installOrientation != other.installOrientation
|| !Objects.equals(displayShape, other.displayShape)
|| hasArrSupport != other.hasArrSupport
- || !Objects.equals(frameRateCategoryRate, other.frameRateCategoryRate)) {
+ || !Objects.equals(frameRateCategoryRate, other.frameRateCategoryRate)
+ || !Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)) {
diff |= DIFF_OTHER;
}
return diff;
@@ -582,6 +588,7 @@ final class DisplayDeviceInfo {
renderFrameRate = other.renderFrameRate;
hasArrSupport = other.hasArrSupport;
frameRateCategoryRate = other.frameRateCategoryRate;
+ supportedRefreshRates = other.supportedRefreshRates;
defaultModeId = other.defaultModeId;
userPreferredModeId = other.userPreferredModeId;
supportedModes = other.supportedModes;
@@ -628,6 +635,7 @@ final class DisplayDeviceInfo {
sb.append(", renderFrameRate ").append(renderFrameRate);
sb.append(", hasArrSupport ").append(hasArrSupport);
sb.append(", frameRateCategoryRate ").append(frameRateCategoryRate);
+ sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates));
sb.append(", defaultModeId ").append(defaultModeId);
sb.append(", userPreferredModeId ").append(userPreferredModeId);
sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index ae74dbecc5f8..3871f2a57f76 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.display;
import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY;
+import static android.Manifest.permission.ADD_MIRROR_DISPLAY;
import static android.Manifest.permission.ADD_TRUSTED_DISPLAY;
import static android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT;
import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT;
@@ -1677,15 +1678,10 @@ public final class DisplayManagerService extends SystemService {
}
private boolean canCreateMirrorDisplays(IVirtualDevice virtualDevice) {
- if (virtualDevice == null) {
- return false;
- }
- try {
- return virtualDevice.canCreateMirrorDisplays();
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to query virtual device for permissions", e);
- return false;
+ if (android.companion.virtualdevice.flags.Flags.enableLimitedVdmRole()) {
+ return checkCallingPermission(ADD_MIRROR_DISPLAY, "canCreateMirrorDisplays");
}
+ return virtualDevice != null;
}
private boolean canProjectVideo(IMediaProjection projection) {
@@ -1818,7 +1814,7 @@ public final class DisplayManagerService extends SystemService {
// display.
if (!canProjectVideo(projection) && !canCreateMirrorDisplays(virtualDevice)
&& !hasVideoOutputPermission("createVirtualDisplayInternal")) {
- throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
+ throw new SecurityException("Requires ADD_MIRROR_DISPLAY, CAPTURE_VIDEO_OUTPUT or "
+ "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
+ "MediaProjection token in order to create a screen sharing virtual "
+ "display. In order to create a virtual display that does not perform "
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index a4bb8c348d3f..0b8f7d5ef2cf 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -249,6 +249,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private int mActiveColorMode;
private boolean mHasArrSupport;
private FrameRateCategoryRate mFrameRateCategoryRate;
+ private float[] mSupportedRefreshRates = new float[0];
private Display.HdrCapabilities mHdrCapabilities;
private boolean mAllmSupported;
private boolean mGameContentTypeSupported;
@@ -316,6 +317,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
changed |= updateGameContentTypeSupport(dynamicInfo.gameContentTypeSupported);
changed |= updateHasArrSupportLocked(dynamicInfo.hasArrSupport);
changed |= updateFrameRateCategoryRatesLocked(dynamicInfo.frameRateCategoryRate);
+ changed |= updateSupportedRefreshatesLocked(dynamicInfo.supportedRefreshRates);
if (changed) {
mHavePendingChanges = true;
@@ -624,6 +626,20 @@ final class LocalDisplayAdapter extends DisplayAdapter {
return true;
}
+ private boolean updateSupportedRefreshatesLocked(float[] supportedRefreshRates) {
+ if (!getFeatureFlags().enableGetSupportedRefreshRates()) {
+ return false;
+ }
+ if (supportedRefreshRates == null) {
+ return false;
+ }
+ if (Arrays.equals(mSupportedRefreshRates, supportedRefreshRates)) {
+ return false;
+ }
+ mSupportedRefreshRates = supportedRefreshRates;
+ return true;
+ }
+
private boolean updateAllmSupport(boolean supported) {
if (mAllmSupported == supported) {
return false;
@@ -708,6 +724,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
mInfo.hdrCapabilities = mHdrCapabilities;
mInfo.hasArrSupport = mHasArrSupport;
mInfo.frameRateCategoryRate = mFrameRateCategoryRate;
+ mInfo.supportedRefreshRates = mSupportedRefreshRates;
mInfo.appVsyncOffsetNanos = mActiveSfDisplayMode.appVsyncOffsetNanos;
mInfo.presentationDeadlineNanos = mActiveSfDisplayMode.presentationDeadlineNanos;
mInfo.state = mState;
@@ -1299,6 +1316,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
pw.println("mDefaultModeId=" + mDefaultModeId);
pw.println("mUserPreferredModeId=" + mUserPreferredModeId);
pw.println("mHasArrSupport=" + mHasArrSupport);
+ pw.println("mSupportedRefreshRates=" + Arrays.toString(mSupportedRefreshRates));
pw.println("mState=" + Display.stateToString(mState));
pw.println("mCommittedState=" + Display.stateToString(mCommittedState));
pw.println("mBrightnessState=" + mBrightnessState);
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 7cfdcafcb610..85465981c473 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -508,6 +508,8 @@ final class LogicalDisplay {
mBaseDisplayInfo.renderFrameRate = deviceInfo.renderFrameRate;
mBaseDisplayInfo.hasArrSupport = deviceInfo.hasArrSupport;
mBaseDisplayInfo.frameRateCategoryRate = deviceInfo.frameRateCategoryRate;
+ mBaseDisplayInfo.supportedRefreshRates = Arrays.copyOf(
+ deviceInfo.supportedRefreshRates, deviceInfo.supportedRefreshRates.length);
mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
mBaseDisplayInfo.userPreferredModeId = deviceInfo.userPreferredModeId;
mBaseDisplayInfo.supportedModes = Arrays.copyOf(
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 7f46bbbf0507..e273c6862fe0 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -243,6 +243,11 @@ public class DisplayManagerFlags {
Flags::autoBrightnessModeBedtimeWear
);
+ private final FlagState mGetSupportedRefreshRatesFlagState = new FlagState(
+ Flags.FLAG_ENABLE_GET_SUPPORTED_REFRESH_RATES,
+ Flags::enableGetSupportedRefreshRates
+ );
+
private final FlagState mEnablePluginManagerFlagState = new FlagState(
Flags.FLAG_ENABLE_PLUGIN_MANAGER,
Flags::enablePluginManager
@@ -528,6 +533,13 @@ public class DisplayManagerFlags {
return mAutoBrightnessModeBedtimeWearFlagState.isEnabled();
}
+ /**
+ * @return {@code true} if supported refresh rate api is enabled.
+ */
+ public boolean enableGetSupportedRefreshRates() {
+ return mGetSupportedRefreshRatesFlagState.isEnabled();
+ }
+
public boolean isPluginManagerEnabled() {
return mEnablePluginManagerFlagState.isEnabled();
}
@@ -590,6 +602,7 @@ public class DisplayManagerFlags {
pw.println(" " + mIsUserRefreshRateForExternalDisplayEnabled);
pw.println(" " + mHasArrSupport);
pw.println(" " + mAutoBrightnessModeBedtimeWearFlagState);
+ pw.println(" " + mGetSupportedRefreshRatesFlagState);
pw.println(" " + mEnablePluginManagerFlagState);
pw.println(" " + mDisplayListenerPerformanceImprovementsFlagState);
}
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index 0e7d2b631833..a06f9ef634d1 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -524,6 +524,13 @@ final class Constants {
static final String PROPERTY_DISABLE_CEC_ON_STANDBY_IN_LOW_ENERGY_MODE =
"persist.sys.hdmi.property_disable_cec_on_standby_in_low_energy_mode";
+ /**
+ * Property that checks if CEC was manually enabled by the user in offline mode. With the help
+ * of this property we avoid turning off CEC when the device goes to sleep and if the device
+ * is in low energy mode.
+ */
+ static final String PROPERTY_USER_ACTION_KEEP_CEC_ENABLED_IN_OFFLINE_MODE =
+ "persist.sys.hdmi.property_user_action_keep_cec_enabled_in_offline_mode";
static final int RECORDING_TYPE_DIGITAL_RF = 1;
static final int RECORDING_TYPE_ANALOGUE_RF = 2;
static final int RECORDING_TYPE_EXTERNAL_PHYSICAL_ADDRESS = 3;
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 0c5069f81774..6e98bff8dda5 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -4027,7 +4027,8 @@ public class HdmiControlService extends SystemService {
return;
}
if (isTvDevice() && getDisableCecOnStandbyByLowEnergyMode()
- && mPowerManager.isLowPowerStandbyEnabled()) {
+ && mPowerManager.isLowPowerStandbyEnabled()
+ && !userEnabledCecInOfflineMode()) {
Slog.w(TAG, "Disable CEC on standby due to low power energy mode.");
setWasCecDisabledOnStandbyByLowEnergyMode(true);
getHdmiCecConfig().setIntValue(
@@ -5225,4 +5226,14 @@ public class HdmiControlService extends SystemService {
Constants.PROPERTY_WAS_CEC_DISABLED_ON_STANDBY_BY_LOW_ENERGY_MODE,
String.valueOf(value));
}
+
+ /**
+ * Reads the property that checks if CEC was enabled by the user while in offline mode such that
+ * it won't be disabled when going to sleep by low energy mode.
+ */
+ @VisibleForTesting
+ protected boolean userEnabledCecInOfflineMode() {
+ return SystemProperties.getBoolean(
+ Constants.PROPERTY_USER_ACTION_KEEP_CEC_ENABLED_IN_OFFLINE_MODE, false);
+ }
}
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index d13244905633..da2089131b9f 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
@@ -19,13 +19,19 @@ package com.android.server.inputmethod;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import android.annotation.NonNull;
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.Region;
import android.os.InputConfig;
import android.os.Process;
+import android.util.Slog;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
import android.view.InputWindowHandle;
import android.view.SurfaceControl;
import android.view.WindowManager;
+import android.view.WindowMetrics;
+import android.view.inputmethod.Flags;
import com.android.server.input.InputManagerService;
@@ -39,8 +45,8 @@ final class HandwritingEventReceiverSurface {
private final SurfaceControl mInputSurface;
private boolean mIsIntercepting;
- HandwritingEventReceiverSurface(String name, int displayId, @NonNull SurfaceControl sc,
- @NonNull InputChannel inputChannel) {
+ HandwritingEventReceiverSurface(Context context, String name, int displayId,
+ @NonNull SurfaceControl sc, @NonNull InputChannel inputChannel) {
mClientChannel = inputChannel;
mInputSurface = sc;
@@ -59,15 +65,31 @@ final class HandwritingEventReceiverSurface {
| InputConfig.SPY
| InputConfig.INTERCEPTS_STYLUS;
- // Configure the surface to receive stylus events across the entire display.
- mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
+ Rect bounds = null;
+ if (Flags.adaptiveHandwritingBounds()) {
+ mWindowHandle.setTouchableRegionCrop(mInputSurface);
+ // Default touchable area to getMaximumWindowMetrics()
+ WindowMetrics windowMetrics = context.getSystemService(WindowManager.class)
+ .getMaximumWindowMetrics();
+ bounds = windowMetrics.getBounds();
+ if (DEBUG) Slog.d(TAG, "initial handwriting touchable bounds: " + bounds);
+ mWindowHandle.setTouchableRegion(windowMetrics.getBounds());
+ } else {
+ // Configure the surface to receive stylus events across the entire display.
+ mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
+ }
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
mWindowHandle.setTrustedOverlay(t, mInputSurface, true);
t.setInputWindowInfo(mInputSurface, mWindowHandle);
t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_HANDWRITING_SURFACE);
t.setPosition(mInputSurface, 0, 0);
- t.setCrop(mInputSurface, null /* crop to parent surface */);
+ if (Flags.adaptiveHandwritingBounds()) {
+ // crop to parent surface if null, else bounds.
+ t.setCrop(mInputSurface, bounds);
+ } else {
+ t.setCrop(mInputSurface, null /* crop to parent surface */);
+ }
t.show(mInputSurface);
t.apply();
@@ -79,12 +101,23 @@ final class HandwritingEventReceiverSurface {
mWindowHandle.ownerUid = imeUid;
mWindowHandle.inputConfig &= ~InputConfig.SPY;
+ if (Flags.adaptiveHandwritingBounds()) {
+ // watch outside touch to finish handwriting.
+ mWindowHandle.inputConfig |= InputConfig.WATCH_OUTSIDE_TOUCH;
+ }
new SurfaceControl.Transaction()
.setInputWindowInfo(mInputSurface, mWindowHandle)
.apply();
mIsIntercepting = true;
}
+ void setTouchableRegion(Region touchableRegion) {
+ mWindowHandle.touchableRegion.set(touchableRegion);
+ new SurfaceControl.Transaction()
+ .setInputWindowInfo(mInputSurface, mWindowHandle)
+ .apply();
+ }
+
void setNotTouchable(boolean notTouchable) {
if (notTouchable) {
mWindowHandle.inputConfig |= InputConfig.NOT_TOUCHABLE;
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
index c19cb030ef37..45d7d0464fe1 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
@@ -27,6 +27,7 @@ import android.annotation.UiThread;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManagerInternal;
+import android.graphics.Region;
import android.hardware.input.InputManager;
import android.hardware.input.InputManagerGlobal;
import android.os.Handler;
@@ -139,7 +140,7 @@ final class HandwritingModeController {
}
mHandwritingSurface = new HandwritingEventReceiverSurface(
- name, displayId, surface, channel);
+ mContext, name, displayId, surface, channel);
// Use a dup of the input channel so that event processing can be paused by disposing the
// event receiver without causing a fd hangup.
@@ -163,6 +164,13 @@ final class HandwritingModeController {
mHandwritingSurface.setNotTouchable(notTouchable);
}
+ void setHandwritingTouchableRegion(Region region) {
+ if (!getCurrentRequestId().isPresent()) {
+ return;
+ }
+ mHandwritingSurface.setTouchableRegion(region);
+ }
+
boolean isStylusGestureOngoing() {
if (mRecordingGestureAfterStylusUp && !mHandwritingBuffer.isEmpty()) {
// If it is less than AFTER_STYLUS_UP_ALLOW_PERIOD_MS after the stylus up event, return
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 76049ca824c2..d177d0e5f2eb 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -34,6 +34,7 @@ import android.hardware.contexthub.ErrorCode;
import android.hardware.contexthub.HubEndpointInfo;
import android.hardware.contexthub.IContextHubEndpoint;
import android.hardware.contexthub.IContextHubEndpointCallback;
+import android.hardware.contexthub.IContextHubEndpointDiscoveryCallback;
import android.hardware.contexthub.MessageDeliveryStatus;
import android.hardware.location.ContextHubInfo;
import android.hardware.location.ContextHubMessage;
@@ -793,6 +794,31 @@ public class ContextHubService extends IContextHubService.Stub {
return null;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+ @Override
+ public void registerEndpointDiscoveryCallbackId(
+ long endpointId, IContextHubEndpointDiscoveryCallback callback) throws RemoteException {
+ super.registerEndpointDiscoveryCallbackId_enforcePermission();
+ // TODO(b/375487784): Implement this
+ }
+
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+ @Override
+ public void registerEndpointDiscoveryCallbackDescriptor(
+ String serviceDescriptor, IContextHubEndpointDiscoveryCallback callback)
+ throws RemoteException {
+ super.registerEndpointDiscoveryCallbackDescriptor_enforcePermission();
+ // TODO(b/375487784): Implement this
+ }
+
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
+ @Override
+ public void unregisterEndpointDiscoveryCallback(IContextHubEndpointDiscoveryCallback callback)
+ throws RemoteException {
+ super.unregisterEndpointDiscoveryCallback_enforcePermission();
+ // TODO(b/375487784): Implement this
+ }
+
/**
* Creates an internal load transaction callback to be used for old API clients
*
diff --git a/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java b/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java
index 6c74cba99bcb..05fe78114eca 100644
--- a/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java
+++ b/services/core/java/com/android/server/media/projection/FrameworkStatsLogWrapper.java
@@ -30,7 +30,8 @@ public class FrameworkStatsLogWrapper {
int hostUid,
int targetUid,
int timeSinceLastActive,
- int creationSource) {
+ int creationSource,
+ int stopSource) {
FrameworkStatsLog.write(
code,
sessionId,
@@ -39,7 +40,8 @@ public class FrameworkStatsLogWrapper {
hostUid,
targetUid,
timeSinceLastActive,
- creationSource);
+ creationSource,
+ stopSource);
}
/** Wrapper around {@link FrameworkStatsLog#write} for MediaProjectionTargetChanged atom. */
@@ -49,13 +51,23 @@ public class FrameworkStatsLogWrapper {
int targetType,
int hostUid,
int targetUid,
- int windowingMode) {
+ int windowingMode,
+ int width,
+ int height,
+ int centerX,
+ int centerY,
+ int targetChangeType) {
FrameworkStatsLog.write(
code,
sessionId,
targetType,
hostUid,
targetUid,
- windowingMode);
+ windowingMode,
+ width,
+ height,
+ centerX,
+ centerY,
+ targetChangeType);
}
}
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index df5ecf872df4..c428f39fd9d0 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -51,6 +51,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ServiceInfo;
+import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.media.MediaRouter;
import android.media.projection.IMediaProjection;
@@ -60,6 +61,7 @@ import android.media.projection.IMediaProjectionWatcherCallback;
import android.media.projection.MediaProjectionInfo;
import android.media.projection.MediaProjectionManager;
import android.media.projection.ReviewGrantedConsentResult;
+import android.media.projection.StopReason;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
@@ -178,7 +180,7 @@ public final class MediaProjectionManagerService extends SystemService
if (!mMediaProjectionStopController.isExemptFromStopping(mProjectionGrant, reason)) {
Slog.d(TAG, "Content Recording: Stopping MediaProjection due to "
+ MediaProjectionStopController.stopReasonToString(reason));
- mProjectionGrant.stop();
+ mProjectionGrant.stop(StopReason.STOP_DEVICE_LOCKED);
}
}
}
@@ -257,7 +259,7 @@ public final class MediaProjectionManagerService extends SystemService
synchronized (mLock) {
if (mProjectionGrant != null) {
Slog.d(TAG, "Content Recording: Stopped MediaProjection due to user switching");
- mProjectionGrant.stop();
+ mProjectionGrant.stop(StopReason.STOP_USER_SWITCH);
}
}
}
@@ -295,7 +297,7 @@ public final class MediaProjectionManagerService extends SystemService
Slog.d(TAG,
"Content Recording: Stopped MediaProjection due to foreground service change");
if (mProjectionGrant != null) {
- mProjectionGrant.stop();
+ mProjectionGrant.stop(StopReason.STOP_FOREGROUND_SERVICE_CHANGE);
}
}
}
@@ -304,7 +306,7 @@ public final class MediaProjectionManagerService extends SystemService
if (mProjectionGrant != null) {
Slog.d(TAG, "Content Recording: Stopped MediaProjection to start new "
+ "incoming projection");
- mProjectionGrant.stop();
+ mProjectionGrant.stop(StopReason.STOP_NEW_PROJECTION);
}
if (mMediaRouteInfo != null) {
mMediaRouter.getFallbackRoute().select();
@@ -314,7 +316,10 @@ public final class MediaProjectionManagerService extends SystemService
dispatchStart(projection);
}
- private void stopProjectionLocked(final MediaProjection projection) {
+ private void stopProjectionLocked(
+ final MediaProjection projection,
+ @StopReason int stopReason
+ ) {
Slog.d(TAG, "Content Recording: Stopped active MediaProjection and "
+ "dispatching stop to callbacks");
ContentRecordingSession session = projection.mSession;
@@ -322,7 +327,7 @@ public final class MediaProjectionManagerService extends SystemService
session != null
? session.getTargetUid()
: ContentRecordingSession.TARGET_UID_UNKNOWN;
- mMediaProjectionMetricsLogger.logStopped(projection.uid, targetUid);
+ mMediaProjectionMetricsLogger.logStopped(projection.uid, targetUid, stopReason);
mProjectionToken = null;
mProjectionGrant = null;
dispatchStop(projection);
@@ -403,7 +408,7 @@ public final class MediaProjectionManagerService extends SystemService
+ "ContentRecordingSession - id= "
+ mProjectionGrant.getVirtualDisplayId() + "type=" + projectionType);
- mProjectionGrant.stop();
+ mProjectionGrant.stop(StopReason.STOP_ERROR);
}
return false;
}
@@ -517,6 +522,18 @@ public final class MediaProjectionManagerService extends SystemService
}
}
+ @VisibleForTesting
+ void notifyCaptureBoundsChanged(int contentToRecord, int targetUid, Rect captureBounds) {
+ synchronized (mLock) {
+ if (mProjectionGrant == null) {
+ Slog.i(TAG, "Cannot log MediaProjectionTargetChanged atom due to null projection");
+ } else {
+ mMediaProjectionMetricsLogger.logChangedCaptureBounds(
+ contentToRecord, mProjectionGrant.uid, targetUid, captureBounds);
+ }
+ }
+ }
+
/**
* Handles result of dialog shown from
* {@link BinderService#buildReviewGrantedConsentIntentLocked()}.
@@ -557,7 +574,7 @@ public final class MediaProjectionManagerService extends SystemService
Slog.w(TAG, "Content Recording: Stopped MediaProjection due to user "
+ "consent result of CANCEL - "
+ "id= " + mProjectionGrant.getVirtualDisplayId());
- mProjectionGrant.stop();
+ mProjectionGrant.stop(StopReason.STOP_ERROR);
}
break;
case RECORD_CONTENT_DISPLAY:
@@ -773,14 +790,14 @@ public final class MediaProjectionManagerService extends SystemService
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
@Override // Binder call
- public void stopActiveProjection() {
+ public void stopActiveProjection(@StopReason int stopReason) {
stopActiveProjection_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
if (mProjectionGrant != null) {
Slog.d(TAG, "Content Recording: Stopping active projection");
- mProjectionGrant.stop();
+ mProjectionGrant.stop(stopReason);
}
}
} finally {
@@ -790,8 +807,9 @@ public final class MediaProjectionManagerService extends SystemService
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
@Override // Binder call
- public void notifyActiveProjectionCapturedContentResized(int width, int height) {
- notifyActiveProjectionCapturedContentResized_enforcePermission();
+ public void notifyCaptureBoundsChanged(
+ int contentToRecord, int targetProcessUid, Rect newBounds) {
+ notifyCaptureBoundsChanged_enforcePermission();
synchronized (mLock) {
if (!isCurrentProjection(mProjectionGrant)) {
return;
@@ -801,7 +819,13 @@ public final class MediaProjectionManagerService extends SystemService
try {
synchronized (mLock) {
if (mProjectionGrant != null && mCallbackDelegate != null) {
- mCallbackDelegate.dispatchResize(mProjectionGrant, width, height);
+ // log metrics for the new bounds
+ MediaProjectionManagerService.this.notifyCaptureBoundsChanged(
+ contentToRecord, targetProcessUid, newBounds);
+
+ // update clients of the new update bounds
+ mCallbackDelegate.dispatchResize(
+ mProjectionGrant, newBounds.width(), newBounds.height());
}
}
} finally {
@@ -1133,7 +1157,7 @@ public final class MediaProjectionManagerService extends SystemService
Slog.d(TAG, "Content Recording: MediaProjection stopped by Binder death - "
+ "id= " + mVirtualDisplayId);
mCallbackDelegate.remove(callback);
- stop();
+ stop(StopReason.STOP_TARGET_REMOVED);
};
mToken.linkToDeath(mDeathEater, 0);
} catch (RemoteException e) {
@@ -1182,7 +1206,7 @@ public final class MediaProjectionManagerService extends SystemService
}
@Override // Binder call
- public void stop() {
+ public void stop(@StopReason int stopReason) {
synchronized (mLock) {
if (!isCurrentProjection(asBinder())) {
Slog.w(TAG, "Attempted to stop inactive MediaProjection "
@@ -1211,7 +1235,7 @@ public final class MediaProjectionManagerService extends SystemService
Slog.d(TAG, "Content Recording: handling stopping this projection token"
+ " createTime= " + mCreateTimeMillis
+ " countStarts= " + mCountStarts);
- stopProjectionLocked(this);
+ stopProjectionLocked(this, stopReason);
mToken.unlinkToDeath(mDeathEater, 0);
mToken = null;
unregisterCallback(mCallback);
@@ -1295,7 +1319,7 @@ public final class MediaProjectionManagerService extends SystemService
Slog.v(TAG, "Reusing token: Throw exception due to invalid projection.");
// Tear down projection here; necessary to ensure (among other reasons) that
// stop is dispatched to client and cast icon disappears from status bar.
- mProjectionGrant.stop();
+ mProjectionGrant.stop(StopReason.STOP_ERROR);
throw new SecurityException("Don't re-use the resultData to retrieve "
+ "the same projection instance, and don't use a token that has "
+ "timed out. Don't take multiple captures by invoking "
@@ -1315,10 +1339,9 @@ public final class MediaProjectionManagerService extends SystemService
Slog.w(TAG,
"Content Recording: MediaProjection start disallowed, aborting "
+ "MediaProjection");
- stop();
+ stop(StopReason.STOP_DEVICE_LOCKED);
return;
}
-
mVirtualDisplayId = displayId;
// If prior session was does not have a valid display id, then update the display
@@ -1357,7 +1380,7 @@ public final class MediaProjectionManagerService extends SystemService
if (mProjectionGrant != null) {
Slog.d(TAG, "Content Recording: Stopped MediaProjection due to "
+ "route type of REMOTE_DISPLAY not selected");
- mProjectionGrant.stop();
+ mProjectionGrant.stop(StopReason.STOP_NEW_MEDIA_ROUTE);
}
}
}
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java b/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
index be2a25a755a5..8e5c01685275 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionMetricsLogger.java
@@ -19,15 +19,34 @@ package com.android.server.media.projection;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY;
import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CANCELLED;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_DEVICE_LOCK;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_ERROR;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_FOREGROUND_SERVICE_CHANGE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_HOST_APP_STOP;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_MEDIA_ROUTE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_PROJECTION;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_QS_TILE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_STATUS_BAR_CHIP_STOP;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_TASK_APP_CLOSE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_APP_SELECTOR_DISPLAYED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_USER_SWITCH;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_BOUNDS;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_POSITION;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_WINDOWING_MODE;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_APP_TASK;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_DISPLAY;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_UNKNOWN;
@@ -36,8 +55,12 @@ import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGE
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_SPLIT_SCREEN;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_UNKNOWN;
+import android.app.WindowConfiguration;
import android.app.WindowConfiguration.WindowingMode;
import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.media.projection.StopReason;
import android.util.Log;
import android.view.ContentRecordingSession.RecordContent;
@@ -59,8 +82,10 @@ public class MediaProjectionMetricsLogger {
private final MediaProjectionSessionIdGenerator mSessionIdGenerator;
private final MediaProjectionTimestampStore mTimestampStore;
- private int mPreviousState =
- FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN;
+ private final Rect mPreviousTargetBounds = new Rect();
+ private int mPreviousTargetWindowingMode = WINDOWING_MODE_UNDEFINED;
+ private int mPreviousProjectionState =
+ MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN;
MediaProjectionMetricsLogger(
FrameworkStatsLogWrapper frameworkStatsLogWrapper,
@@ -113,7 +138,8 @@ public class MediaProjectionMetricsLogger {
hostUid,
TARGET_UID_UNKNOWN,
timeSinceLastActiveInSeconds,
- sessionCreationSource);
+ sessionCreationSource,
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
}
/**
@@ -130,7 +156,8 @@ public class MediaProjectionMetricsLogger {
hostUid,
TARGET_UID_UNKNOWN,
TIME_SINCE_LAST_ACTIVE_UNKNOWN,
- MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
+ MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN,
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
}
/**
@@ -141,13 +168,12 @@ public class MediaProjectionMetricsLogger {
public void logProjectionPermissionRequestCancelled(int hostUid) {
writeStateChanged(
mSessionIdGenerator.getCurrentSessionId(),
- FrameworkStatsLog
- .MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CANCELLED,
+ MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CANCELLED,
hostUid,
TARGET_UID_UNKNOWN,
TIME_SINCE_LAST_ACTIVE_UNKNOWN,
- FrameworkStatsLog
- .MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
+ MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN,
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
}
/**
@@ -163,7 +189,8 @@ public class MediaProjectionMetricsLogger {
hostUid,
TARGET_UID_UNKNOWN,
TIME_SINCE_LAST_ACTIVE_UNKNOWN,
- MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
+ MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN,
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
}
/**
@@ -180,7 +207,8 @@ public class MediaProjectionMetricsLogger {
hostUid,
targetUid,
TIME_SINCE_LAST_ACTIVE_UNKNOWN,
- MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
+ MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN,
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
}
/**
@@ -196,14 +224,63 @@ public class MediaProjectionMetricsLogger {
*/
public void logChangedWindowingMode(
int contentToRecord, int hostUid, int targetUid, int windowingMode) {
- Log.d(TAG, "logChangedWindowingMode");
+ Log.d(TAG, "logChangedWindowingMode: windowingMode= "
+ + WindowConfiguration.windowingModeToString(windowingMode));
+ Log.d(TAG, "targetChangeType= changeWindowingMode");
writeTargetChanged(
mSessionIdGenerator.getCurrentSessionId(),
contentToRecordToTargetType(contentToRecord),
hostUid,
targetUid,
- windowingModeToTargetWindowingMode(windowingMode));
+ windowingModeToTargetWindowingMode(windowingMode),
+ mPreviousTargetBounds.width(),
+ mPreviousTargetBounds.height(),
+ mPreviousTargetBounds.centerX(),
+ mPreviousTargetBounds.centerY(),
+ MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_WINDOWING_MODE);
+ mPreviousTargetWindowingMode = windowingMode;
+ }
+ /**
+ * Logs that the bounds of projection's capture target has changed.
+ *
+ * @param contentToRecord ContentRecordingSession.RecordContent indicating whether it is a
+ * task capture or display capture - gets converted to the corresponding
+ * TargetType before being logged.
+ * @param hostUid UID of the package that initiates MediaProjection.
+ * @param targetUid UID of the package that is captured if selected.
+ * @param captureBounds Updated bounds of the captured region.
+ */
+ public void logChangedCaptureBounds(
+ int contentToRecord, int hostUid, int targetUid, Rect captureBounds) {
+ final Point capturePosition = new Point(captureBounds.centerX(), captureBounds.centerY());
+ Log.d(TAG, "logChangedCaptureBounds: captureBounds= " + captureBounds + " position= "
+ + capturePosition);
+
+ writeTargetChanged(
+ mSessionIdGenerator.getCurrentSessionId(),
+ contentToRecordToTargetType(contentToRecord),
+ hostUid,
+ targetUid,
+ mPreviousTargetWindowingMode,
+ captureBounds.width(),
+ captureBounds.height(),
+ captureBounds.centerX(),
+ captureBounds.centerY(),
+ captureBoundsToTargetChangeType(captureBounds));
+ mPreviousTargetBounds.set(captureBounds);
+ }
+
+ private int captureBoundsToTargetChangeType(Rect captureBounds) {
+ final boolean hasChangedSize = captureBounds.width() != mPreviousTargetBounds.width()
+ && captureBounds.height() != mPreviousTargetBounds.height();
+
+ if (hasChangedSize) {
+ Log.d(TAG, "targetChangeType= changeBounds");
+ return MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_BOUNDS;
+ }
+ Log.d(TAG, "targetChangeType= changePosition");
+ return MEDIA_PROJECTION_TARGET_CHANGED__TARGET_CHANGE_TYPE__TARGET_CHANGE_POSITION;
}
@VisibleForTesting
@@ -231,45 +308,85 @@ public class MediaProjectionMetricsLogger {
};
}
+ @VisibleForTesting
+ public int stopReasonToSessionStopSource(@StopReason int stopReason) {
+ return switch (stopReason) {
+ case StopReason.STOP_HOST_APP ->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_HOST_APP_STOP;
+ case StopReason.STOP_TARGET_REMOVED ->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_TASK_APP_CLOSE;
+ case StopReason.STOP_DEVICE_LOCKED->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_DEVICE_LOCK;
+ case StopReason.STOP_PRIVACY_CHIP ->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_STATUS_BAR_CHIP_STOP;
+ case StopReason.STOP_QS_TILE ->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_QS_TILE;
+ case StopReason.STOP_USER_SWITCH ->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_USER_SWITCH;
+ case StopReason.STOP_FOREGROUND_SERVICE_CHANGE ->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_FOREGROUND_SERVICE_CHANGE;
+ case StopReason.STOP_NEW_PROJECTION ->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_PROJECTION;
+ case StopReason.STOP_NEW_MEDIA_ROUTE ->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_MEDIA_ROUTE;
+ case StopReason.STOP_ERROR ->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_ERROR;
+ default ->
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN;
+ };
+ }
+
/**
* Logs that the capturing stopped, either normally or because of error.
*
* @param hostUid UID of the package that initiates MediaProjection.
* @param targetUid UID of the package that is captured if selected.
*/
- public void logStopped(int hostUid, int targetUid) {
+ public void logStopped(int hostUid, int targetUid, int stopReason) {
boolean wasCaptureInProgress =
- mPreviousState
+ mPreviousProjectionState
== MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS;
- Log.d(TAG, "logStopped: wasCaptureInProgress=" + wasCaptureInProgress);
+ Log.d(TAG, "logStopped: wasCaptureInProgress=" + wasCaptureInProgress +
+ " stopReason=" + stopReason);
writeStateChanged(
mSessionIdGenerator.getCurrentSessionId(),
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED,
hostUid,
targetUid,
TIME_SINCE_LAST_ACTIVE_UNKNOWN,
- MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
+ MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN,
+ stopReasonToSessionStopSource(stopReason));
if (wasCaptureInProgress) {
mTimestampStore.registerActiveSessionEnded();
}
}
- public void notifyProjectionStateChange(int hostUid, int state, int sessionCreationSource) {
- writeStateChanged(hostUid, state, sessionCreationSource);
+ public void notifyProjectionStateChange(
+ int hostUid,
+ int state,
+ int sessionCreationSource,
+ int sessionStopSource
+ ) {
+ writeStateChanged(hostUid, state, sessionCreationSource, sessionStopSource);
}
- private void writeStateChanged(int hostUid, int state, int sessionCreationSource) {
+ private void writeStateChanged(
+ int hostUid,
+ int state,
+ int sessionCreationSource,
+ int sessionStopSource
+ ) {
mFrameworkStatsLogWrapper.writeStateChanged(
- /* code */ FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED,
+ /* code */ MEDIA_PROJECTION_STATE_CHANGED,
/* session_id */ 123,
/* state */ state,
- /* previous_state */ FrameworkStatsLog
- .MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN,
+ /* previous_state */ MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN,
/* host_uid */ hostUid,
/* target_uid */ -1,
/* time_since_last_active */ 0,
- /* creation_source */ sessionCreationSource);
+ /* creation_source */ sessionCreationSource,
+ /* stop_source */ sessionStopSource);
}
private void writeStateChanged(
@@ -278,17 +395,19 @@ public class MediaProjectionMetricsLogger {
int hostUid,
int targetUid,
int timeSinceLastActive,
- int creationSource) {
+ int creationSource,
+ int stopSource) {
mFrameworkStatsLogWrapper.writeStateChanged(
- /* code */ FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED,
+ /* code */ MEDIA_PROJECTION_STATE_CHANGED,
sessionId,
state,
- mPreviousState,
+ mPreviousProjectionState,
hostUid,
targetUid,
timeSinceLastActive,
- creationSource);
- mPreviousState = state;
+ creationSource,
+ stopSource);
+ mPreviousProjectionState = state;
}
private void writeTargetChanged(
@@ -296,13 +415,23 @@ public class MediaProjectionMetricsLogger {
int targetType,
int hostUid,
int targetUid,
- int targetWindowingMode) {
+ int targetWindowingMode,
+ int width,
+ int height,
+ int centerX,
+ int centerY,
+ int targetChangeType) {
mFrameworkStatsLogWrapper.writeTargetChanged(
- /* code */ FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED,
+ /* code */ MEDIA_PROJECTION_TARGET_CHANGED,
sessionId,
targetType,
hostUid,
targetUid,
- targetWindowingMode);
+ targetWindowingMode,
+ width,
+ height,
+ centerX,
+ centerY,
+ targetChangeType);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e019267f21cd..15af36ba66af 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -6597,6 +6597,14 @@ public class NotificationManagerService extends SystemService {
android.Manifest.permission.INTERACT_ACROSS_USERS,
"setNotificationListenerAccessGrantedForUser for user " + userId);
}
+ if (mUmInternal.isVisibleBackgroundFullUser(userId)) {
+ // The main use case for visible background users is the Automotive multi-display
+ // configuration where a passenger can use a secondary display while the driver is
+ // using the main display. NotificationListeners is designed only for the current
+ // user and work profile. We added a condition to prevent visible background users
+ // from updating the data managed within the NotificationListeners object.
+ return;
+ }
checkNotificationListenerAccess();
if (granted && listener.flattenToString().length()
> NotificationManager.MAX_SERVICE_COMPONENT_NAME_LENGTH) {
@@ -12746,6 +12754,20 @@ public class NotificationManagerService extends SystemService {
}
@Override
+ public void onUserUnlocked(int user) {
+ if (mUmInternal.isVisibleBackgroundFullUser(user)) {
+ // The main use case for visible background users is the Automotive
+ // multi-display configuration where a passenger can use a secondary
+ // display while the driver is using the main display.
+ // NotificationListeners is designed only for the current user and work
+ // profile. We added a condition to prevent visible background users from
+ // updating the data managed within the NotificationListeners object.
+ return;
+ }
+ super.onUserUnlocked(user);
+ }
+
+ @Override
protected boolean allowRebindForParentUser() {
return true;
}
diff --git a/services/core/java/com/android/server/pm/InstallDependencyHelper.java b/services/core/java/com/android/server/pm/InstallDependencyHelper.java
index 527d68049537..5bd2c994160c 100644
--- a/services/core/java/com/android/server/pm/InstallDependencyHelper.java
+++ b/services/core/java/com/android/server/pm/InstallDependencyHelper.java
@@ -16,6 +16,7 @@
package com.android.server.pm;
+import static android.content.pm.PackageInstaller.ACTION_INSTALL_DEPENDENCY;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
import static android.os.Process.SYSTEM_UID;
@@ -23,6 +24,7 @@ import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.dependencyinstaller.DependencyInstallerCallback;
@@ -33,12 +35,14 @@ import android.os.Handler;
import android.os.OutcomeReceiver;
import android.os.Process;
import android.os.RemoteException;
+import android.util.ArraySet;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.infra.AndroidFuture;
import com.android.internal.infra.ServiceConnector;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -48,22 +52,25 @@ import java.util.concurrent.TimeUnit;
public class InstallDependencyHelper {
private static final String TAG = InstallDependencyHelper.class.getSimpleName();
private static final boolean DEBUG = true;
- private static final String ACTION_INSTALL_DEPENDENCY =
- "android.intent.action.INSTALL_DEPENDENCY";
// The maximum amount of time to wait before the system unbinds from the verifier.
private static final long UNBIND_TIMEOUT_MILLIS = TimeUnit.HOURS.toMillis(6);
private static final long REQUEST_TIMEOUT_MILLIS = TimeUnit.MINUTES.toMillis(1);
- private final SharedLibrariesImpl mSharedLibraries;
private final Context mContext;
+ private final SharedLibrariesImpl mSharedLibraries;
+ private final PackageInstallerService mPackageInstallerService;
private final Object mRemoteServiceLock = new Object();
+ @GuardedBy("mTrackers")
+ private final List<DependencyInstallTracker> mTrackers = new ArrayList<>();
@GuardedBy("mRemoteServiceLock")
private ServiceConnector<IDependencyInstallerService> mRemoteService = null;
- InstallDependencyHelper(Context context, SharedLibrariesImpl sharedLibraries) {
+ InstallDependencyHelper(Context context, SharedLibrariesImpl sharedLibraries,
+ PackageInstallerService packageInstallerService) {
mContext = context;
mSharedLibraries = sharedLibraries;
+ mPackageInstallerService = packageInstallerService;
}
void resolveLibraryDependenciesIfNeeded(PackageLite pkg, Computer snapshot, int userId,
@@ -98,19 +105,8 @@ public class InstallDependencyHelper {
return;
}
- IDependencyInstallerCallback serviceCallback = new IDependencyInstallerCallback.Stub() {
- @Override
- public void onAllDependenciesResolved(int[] sessionIds) throws RemoteException {
- // TODO(b/372862145): Implement waiting for sessions to finish installation
- callback.onResult(null);
- }
-
- @Override
- public void onFailureToResolveAllDependencies() throws RemoteException {
- onError(callback, "Failed to resolve all dependencies automatically");
- }
- };
-
+ IDependencyInstallerCallback serviceCallback =
+ new DependencyInstallerCallbackCallOnce(handler, callback);
boolean scheduleSuccess;
synchronized (mRemoteServiceLock) {
scheduleSuccess = mRemoteService.run(service -> {
@@ -123,10 +119,28 @@ public class InstallDependencyHelper {
}
}
- private void onError(CallOnceProxy callback, String msg) {
+ void notifySessionComplete(int sessionId, boolean success) {
+ if (DEBUG) {
+ Slog.i(TAG, "Session complete for " + sessionId + " result: " + success);
+ }
+ synchronized (mTrackers) {
+ List<DependencyInstallTracker> completedTrackers = new ArrayList<>();
+ for (DependencyInstallTracker tracker: mTrackers) {
+ if (!tracker.onSessionComplete(sessionId, success)) {
+ completedTrackers.add(tracker);
+ }
+ }
+ mTrackers.removeAll(completedTrackers);
+ }
+ }
+
+ private static void onError(CallOnceProxy callback, String msg) {
PackageManagerException pe = new PackageManagerException(
INSTALL_FAILED_MISSING_SHARED_LIBRARY, msg);
callback.onError(pe);
+ if (DEBUG) {
+ Slog.i(TAG, "Orig session error: " + msg);
+ }
}
private boolean bindToDependencyInstallerIfNeeded(int userId, Handler handler,
@@ -253,4 +267,135 @@ public class InstallDependencyHelper {
}
}
}
+
+ /**
+ * Ensure we call one of the outcomes only once, on the right handler.
+ *
+ * Repeated calls will be no-op.
+ */
+ private class DependencyInstallerCallbackCallOnce extends IDependencyInstallerCallback.Stub {
+
+ private final Handler mHandler;
+ private final CallOnceProxy mCallback;
+
+ @GuardedBy("this")
+ private boolean mCalled = false;
+
+ DependencyInstallerCallbackCallOnce(Handler handler, CallOnceProxy callback) {
+ mHandler = handler;
+ mCallback = callback;
+ }
+
+ // TODO(b/372862145): Consider turning the binder call to two-way so that we can
+ // throw IllegalArgumentException
+ @Override
+ public void onAllDependenciesResolved(int[] sessionIds) throws RemoteException {
+ synchronized (this) {
+ if (mCalled) {
+ return;
+ }
+ mCalled = true;
+ }
+
+ ArraySet<Integer> set = new ArraySet<>();
+ for (int i = 0; i < sessionIds.length; i++) {
+ if (DEBUG) {
+ Slog.i(TAG, "onAllDependenciesResolved called with " + sessionIds[i]);
+ }
+ set.add(sessionIds[i]);
+ }
+
+ DependencyInstallTracker tracker = new DependencyInstallTracker(mCallback, set);
+ synchronized (mTrackers) {
+ mTrackers.add(tracker);
+ }
+
+ // In case any of the session ids have already been installed, check if they
+ // are valid.
+ mHandler.post(() -> {
+ if (DEBUG) {
+ Slog.i(TAG, "onAllDependenciesResolved cleaning up invalid sessions");
+ }
+
+ for (int i = 0; i < sessionIds.length; i++) {
+ int sessionId = sessionIds[i];
+ SessionInfo sessionInfo = mPackageInstallerService.getSessionInfo(sessionId);
+
+ // Continue waiting if session exists and hasn't passed or failed yet.
+ if (sessionInfo != null && !sessionInfo.isSessionApplied
+ && !sessionInfo.isSessionFailed) {
+ continue;
+ }
+
+ if (DEBUG) {
+ Slog.i(TAG, "onAllDependenciesResolved cleaning up finished"
+ + " session: " + sessionId);
+ }
+
+ // If session info is null, we assume it to be success.
+ // TODO(b/372862145): Check historical sessions to be more precise.
+ boolean success = sessionInfo == null || sessionInfo.isSessionApplied;
+
+ notifySessionComplete(sessionId, /*success=*/success);
+ }
+ });
+ }
+
+ @Override
+ public void onFailureToResolveAllDependencies() throws RemoteException {
+ synchronized (this) {
+ if (mCalled) {
+ return;
+ }
+ onError(mCallback, "Failed to resolve all dependencies automatically");
+ mCalled = true;
+ }
+ }
+ }
+
+ /**
+ * Tracks a list of session ids against a particular callback.
+ *
+ * If all the sessions completes successfully, it invokes the positive flow. If any of the
+ * sessions fails, it invokes the failure flow immediately.
+ */
+ // TODO(b/372862145): Determine and add support for rebooting while dependency is being resolved
+ private static class DependencyInstallTracker {
+ private final CallOnceProxy mCallback;
+ private final ArraySet<Integer> mPendingSessionIds;
+
+ DependencyInstallTracker(CallOnceProxy callback, ArraySet<Integer> pendingSessionIds) {
+ mCallback = callback;
+ mPendingSessionIds = pendingSessionIds;
+ }
+
+ /**
+ * Process a session complete event.
+ *
+ * Returns true if we still need to continue tracking.
+ */
+ public boolean onSessionComplete(int sessionId, boolean success) {
+ synchronized (this) {
+ if (!mPendingSessionIds.contains(sessionId)) {
+ // This had no impact on tracker, so continue tracking
+ return true;
+ }
+
+ if (!success) {
+ // If one of the dependency fails, the orig session would fail too.
+ onError(mCallback, "Failed to install all dependencies");
+ // TODO(b/372862145): Abandon the rest of the pending sessions.
+ return false; // No point in tracking anymore
+ }
+
+ mPendingSessionIds.remove(sessionId);
+ if (mPendingSessionIds.isEmpty()) {
+ mCallback.onResult(null);
+ return false; // Nothing to track anymore
+ }
+ return true; // Keep on tracking
+ }
+ }
+
+ }
}
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 8168c5493304..e5e274450655 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -229,6 +229,7 @@ final class InstallPackageHelper {
private final SharedLibrariesImpl mSharedLibraries;
private final PackageManagerServiceInjector mInjector;
private final UpdateOwnershipHelper mUpdateOwnershipHelper;
+ private final InstallDependencyHelper mInstallDependencyHelper;
private final Object mInternalLock = new Object();
@GuardedBy("mInternalLock")
@@ -239,7 +240,8 @@ final class InstallPackageHelper {
AppDataHelper appDataHelper,
RemovePackageHelper removePackageHelper,
DeletePackageHelper deletePackageHelper,
- BroadcastHelper broadcastHelper) {
+ BroadcastHelper broadcastHelper,
+ InstallDependencyHelper installDependencyHelper) {
mPm = pm;
mInjector = pm.mInjector;
mAppDataHelper = appDataHelper;
@@ -253,6 +255,7 @@ final class InstallPackageHelper {
mPackageAbiHelper = pm.mInjector.getAbiHelper();
mSharedLibraries = pm.mInjector.getSharedLibrariesImpl();
mUpdateOwnershipHelper = pm.mInjector.getUpdateOwnershipHelper();
+ mInstallDependencyHelper = installDependencyHelper;
}
/**
@@ -1364,6 +1367,10 @@ final class InstallPackageHelper {
}
}
}
+
+ for (InstallRequest request : requests) {
+ mInstallDependencyHelper.notifySessionComplete(request.getSessionId(), success);
+ }
}
@GuardedBy("mPm.mInstallLock")
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index a4152a724d64..47b785040d44 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -327,7 +327,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
context, mInstallThread.getLooper(), new AppStateHelper(context));
mPackageArchiver = new PackageArchiver(mContext, mPm);
mInstallDependencyHelper = new InstallDependencyHelper(mContext,
- mPm.mInjector.getSharedLibrariesImpl());
+ mPm.mInjector.getSharedLibrariesImpl(), this);
LocalServices.getService(SystemServiceManager.class).startService(
new Lifecycle(context, this));
@@ -337,6 +337,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
return mStagingManager;
}
+ InstallDependencyHelper getInstallDependencyHelper() {
+ return mInstallDependencyHelper;
+ }
+
boolean okToSendBroadcasts() {
return mOkToSendBroadcasts;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 807445ef062d..715633410575 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2118,7 +2118,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mDeletePackageHelper = new DeletePackageHelper(this, mRemovePackageHelper,
mBroadcastHelper);
mInstallPackageHelper = new InstallPackageHelper(this, mAppDataHelper, mRemovePackageHelper,
- mDeletePackageHelper, mBroadcastHelper);
+ mDeletePackageHelper, mBroadcastHelper,
+ injector.getPackageInstallerService().getInstallDependencyHelper());
mInstantAppRegistry = new InstantAppRegistry(mContext, mPermissionManager,
mInjector.getUserManagerInternal(), mDeletePackageHelper);
diff --git a/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
index 82f39b327cea..b25656ebf47f 100644
--- a/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
+++ b/services/core/java/com/android/server/security/intrusiondetection/IntrusionDetectionEventTransportConnection.java
@@ -60,7 +60,7 @@ public class IntrusionDetectionEventTransportConnection implements ServiceConnec
if (!bindService()) {
return false;
}
- AndroidFuture<Integer> resultFuture = new AndroidFuture<>();
+ AndroidFuture<Boolean> resultFuture = new AndroidFuture<>();
try {
mService.initialize(resultFuture);
} catch (RemoteException e) {
@@ -68,8 +68,8 @@ public class IntrusionDetectionEventTransportConnection implements ServiceConnec
unbindService();
return false;
}
- Integer result = getFutureResult(resultFuture);
- if (result != null && result == 0) {
+ Boolean result = getFutureResult(resultFuture);
+ if (result != null && result == true) {
return true;
} else {
unbindService();
@@ -83,22 +83,22 @@ public class IntrusionDetectionEventTransportConnection implements ServiceConnec
* @return Whether the data is added to the binder service.
*/
public boolean addData(List<IntrusionDetectionEvent> data) {
- AndroidFuture<Integer> resultFuture = new AndroidFuture<>();
+ AndroidFuture<Boolean> resultFuture = new AndroidFuture<>();
try {
mService.addData(data, resultFuture);
} catch (RemoteException e) {
Slog.e(TAG, "Remote Exception", e);
return false;
}
- Integer result = getFutureResult(resultFuture);
- return result != null && result == 0;
+ Boolean result = getFutureResult(resultFuture);
+ return result != null && result == true;
}
/**
* Release the BackupTransport binder service.
*/
public void release() {
- AndroidFuture<Integer> resultFuture = new AndroidFuture<>();
+ AndroidFuture<Boolean> resultFuture = new AndroidFuture<>();
try {
mService.release(resultFuture);
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 887e1861f789..708bca71eced 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -2528,22 +2528,24 @@ public class TrustManagerService extends SystemService {
}
private void notifyDeviceLockedListenersForUser(int userId, boolean locked) {
- int numListeners = mDeviceLockedStateListeners.beginBroadcast();
- try {
- IntStream.range(0, numListeners).forEach(i -> {
- try {
- Integer uid = (Integer) mDeviceLockedStateListeners.getBroadcastCookie(i);
- if (userId == uid.intValue()) {
- mDeviceLockedStateListeners.getBroadcastItem(i)
- .onDeviceLockedStateChanged(locked);
+ synchronized (mDeviceLockedStateListeners) {
+ int numListeners = mDeviceLockedStateListeners.beginBroadcast();
+ try {
+ IntStream.range(0, numListeners).forEach(i -> {
+ try {
+ Integer uid = (Integer) mDeviceLockedStateListeners.getBroadcastCookie(i);
+ if (userId == uid.intValue()) {
+ mDeviceLockedStateListeners.getBroadcastItem(i)
+ .onDeviceLockedStateChanged(locked);
+ }
+ } catch (RemoteException re) {
+ Log.i(TAG, "Service died", re);
}
- } catch (RemoteException re) {
- Log.i(TAG, "Service died", re);
- }
- });
+ });
- } finally {
- mDeviceLockedStateListeners.finishBroadcast();
+ } finally {
+ mDeviceLockedStateListeners.finishBroadcast();
+ }
}
}
}
diff --git a/services/core/java/com/android/server/utils/LazyJniRegistrar.java b/services/core/java/com/android/server/utils/LazyJniRegistrar.java
index ac4a92e12909..6d29e9e58a98 100644
--- a/services/core/java/com/android/server/utils/LazyJniRegistrar.java
+++ b/services/core/java/com/android/server/utils/LazyJniRegistrar.java
@@ -42,6 +42,9 @@ public final class LazyJniRegistrar {
/** Registers native methods for ConsumerIrService. */
public static native void registerConsumerIrService();
+ /** Registers native methods for GameManagerService. */
+ public static native void registerGameManagerService();
+
/** Registers native methods for VrManagerService. */
public static native void registerVrManagerService();
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index d019516cd069..bbef5785dfcb 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1513,11 +1513,15 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
if (wallpaper.getComponent() != null
&& isPackageModified(wallpaper.getComponent().getPackageName())) {
+ ServiceInfo serviceInfo = null;
try {
- mContext.getPackageManager().getServiceInfo(wallpaper.getComponent(),
- PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
- } catch (NameNotFoundException e) {
+ serviceInfo = mIPackageManager.getServiceInfo(
+ wallpaper.getComponent(), PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, wallpaper.userId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call IPackageManager.getServiceInfo", e);
+ }
+ if (serviceInfo == null) {
Slog.e(TAG, "Wallpaper component gone, removing: "
+ wallpaper.getComponent());
clearWallpaperLocked(wallpaper.mWhich, wallpaper.userId, false, null);
@@ -3177,7 +3181,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
throw new IllegalArgumentException("Invalid crop rect supplied: " + crop);
}
int orientation = screenOrientations[i];
- if (orientation == ORIENTATION_UNKNOWN && cropMap.size() > 1) {
+ if (orientation == ORIENTATION_UNKNOWN && crops.size() > 1) {
throw new IllegalArgumentException("Invalid crops supplied: the UNKNOWN"
+ "screen orientation should only be used in a singleton map");
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 7cbacd6b0b82..4b7e74af474c 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -22,7 +22,6 @@ import static android.os.Build.IS_USER;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
import static android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS;
@@ -1784,22 +1783,13 @@ final class AccessibilityController {
mA11yWindowsPopulator.populateVisibleWindowsOnScreenLocked(
mDisplayId, visibleWindows);
- if (!com.android.server.accessibility.Flags.computeWindowChangesOnA11yV2()) {
- windows = buildWindowInfoListLocked(visibleWindows, screenSize);
- }
-
// Gets the top focused display Id and window token for supporting multi-display.
topFocusedDisplayId = mService.mRoot.getTopFocusedDisplayContent().getDisplayId();
topFocusedWindowToken = topFocusedWindowState.mClient.asBinder();
}
- if (com.android.server.accessibility.Flags.computeWindowChangesOnA11yV2()) {
- mCallback.onAccessibilityWindowsChanged(forceSend, topFocusedDisplayId,
- topFocusedWindowToken, screenSize, visibleWindows);
- } else {
- mCallback.onWindowsForAccessibilityChanged(forceSend, topFocusedDisplayId,
- topFocusedWindowToken, windows);
- }
+ mCallback.onAccessibilityWindowsChanged(forceSend, topFocusedDisplayId,
+ topFocusedWindowToken, screenSize, visibleWindows);
// Recycle the windows as we do not need them.
for (final AccessibilityWindowsPopulator.AccessibilityWindow window : visibleWindows) {
@@ -1808,166 +1798,6 @@ final class AccessibilityController {
mInitialized = true;
}
- // Here are old code paths, called when computeWindowChangesOnA11yV2 flag is disabled.
- // LINT.IfChange
-
- /**
- * From a list of windows, decides windows to be exposed to accessibility based on touchable
- * region in the screen.
- */
- private List<WindowInfo> buildWindowInfoListLocked(List<AccessibilityWindow> visibleWindows,
- Point screenSize) {
- final List<WindowInfo> windows = new ArrayList<>();
- final Set<IBinder> addedWindows = mTempBinderSet;
- addedWindows.clear();
-
- boolean focusedWindowAdded = false;
-
- final int visibleWindowCount = visibleWindows.size();
-
- Region unaccountedSpace = mTempRegion;
- unaccountedSpace.set(0, 0, screenSize.x, screenSize.y);
-
- // Iterate until we figure out what is touchable for the entire screen.
- for (int i = 0; i < visibleWindowCount; i++) {
- final AccessibilityWindow a11yWindow = visibleWindows.get(i);
- final Region regionInWindow = new Region();
- a11yWindow.getTouchableRegionInWindow(regionInWindow);
- if (windowMattersToAccessibility(a11yWindow, regionInWindow, unaccountedSpace)) {
- addPopulatedWindowInfo(a11yWindow, regionInWindow, windows, addedWindows);
- if (windowMattersToUnaccountedSpaceComputation(a11yWindow)) {
- updateUnaccountedSpace(a11yWindow, unaccountedSpace);
- }
- focusedWindowAdded |= a11yWindow.isFocused();
- } else if (a11yWindow.isUntouchableNavigationBar()) {
- // If this widow is navigation bar without touchable region, accounting the
- // region of navigation bar inset because all touch events from this region
- // would be received by launcher, i.e. this region is a un-touchable one
- // for the application.
- unaccountedSpace.op(
- getSystemBarInsetsFrame(
- mService.mWindowMap.get(a11yWindow.getWindowInfo().token)),
- unaccountedSpace,
- Region.Op.REVERSE_DIFFERENCE);
- }
-
- if (unaccountedSpace.isEmpty() && focusedWindowAdded) {
- break;
- }
- }
-
- // Remove child/parent references to windows that were not added.
- final int windowCount = windows.size();
- for (int i = 0; i < windowCount; i++) {
- WindowInfo window = windows.get(i);
- if (!addedWindows.contains(window.parentToken)) {
- window.parentToken = null;
- }
- if (window.childTokens != null) {
- final int childTokenCount = window.childTokens.size();
- for (int j = childTokenCount - 1; j >= 0; j--) {
- if (!addedWindows.contains(window.childTokens.get(j))) {
- window.childTokens.remove(j);
- }
- }
- // Leave the child token list if empty.
- }
- }
-
- addedWindows.clear();
-
- return windows;
- }
-
- // Some windows should be excluded from unaccounted space computation, though they still
- // should be reported
- private boolean windowMattersToUnaccountedSpaceComputation(AccessibilityWindow a11yWindow) {
- // Do not account space of trusted non-touchable windows, except the split-screen
- // divider.
- // If it's not trusted, touch events are not sent to the windows behind it.
- if (!a11yWindow.isTouchable()
- && (a11yWindow.getType() != TYPE_DOCK_DIVIDER)
- && a11yWindow.isTrustedOverlay()) {
- return false;
- }
-
- if (a11yWindow.getType() == WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
- return false;
- }
- return true;
- }
-
- private boolean windowMattersToAccessibility(AccessibilityWindow a11yWindow,
- Region regionInScreen, Region unaccountedSpace) {
- if (a11yWindow.isFocused()) {
- return true;
- }
-
- // Ignore non-touchable windows, except the split-screen divider, which is
- // occasionally non-touchable but still useful for identifying split-screen
- // mode and the PIP menu.
- if (!a11yWindow.isTouchable()
- && (a11yWindow.getType() != TYPE_DOCK_DIVIDER
- && !a11yWindow.isPIPMenu())) {
- return false;
- }
-
- // If the window is completely covered by other windows - ignore.
- if (unaccountedSpace.quickReject(regionInScreen)) {
- return false;
- }
-
- // Add windows of certain types not covered by modal windows.
- if (isReportedWindowType(a11yWindow.getType())) {
- return true;
- }
-
- return false;
- }
-
- private void updateUnaccountedSpace(AccessibilityWindow a11yWindow,
- Region unaccountedSpace) {
- if (a11yWindow.getType()
- != WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
- // Account for the space this window takes if the window
- // is not an accessibility overlay which does not change
- // the reported windows.
- final Region touchableRegion = mTempRegion2;
- a11yWindow.getTouchableRegionInScreen(touchableRegion);
- unaccountedSpace.op(touchableRegion, unaccountedSpace,
- Region.Op.REVERSE_DIFFERENCE);
- }
- }
-
- private static void addPopulatedWindowInfo(AccessibilityWindow a11yWindow,
- Region regionInScreen, List<WindowInfo> out, Set<IBinder> tokenOut) {
- final WindowInfo window = a11yWindow.getWindowInfo();
- if (window.token == null) {
- // The window was used in calculating visible windows but does not have an
- // associated IWindow token, so exclude it from the list returned to accessibility.
- return;
- }
- window.regionInScreen.set(regionInScreen);
- window.layer = tokenOut.size();
- out.add(window);
- tokenOut.add(window.token);
- }
-
- private static boolean isReportedWindowType(int windowType) {
- return (windowType != WindowManager.LayoutParams.TYPE_WALLPAPER
- && windowType != WindowManager.LayoutParams.TYPE_BOOT_PROGRESS
- && windowType != WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY
- && windowType != WindowManager.LayoutParams.TYPE_DRAG
- && windowType != WindowManager.LayoutParams.TYPE_INPUT_CONSUMER
- && windowType != WindowManager.LayoutParams.TYPE_POINTER
- && windowType != TYPE_MAGNIFICATION_OVERLAY
- && windowType != WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
- && windowType != WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY
- && windowType != WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION);
- }
-
- // LINT.ThenChange(/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java)
-
private WindowState getTopFocusWindow() {
return mService.mRoot.getTopFocusedDisplayContent().mCurrentFocus;
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index fd2a909f8b05..7fc11e6c3ac9 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -724,8 +724,7 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
}
// Compute system bar insets frame if needed.
- if (com.android.server.accessibility.Flags.computeWindowChangesOnA11yV2()
- && windowState != null && instance.isUntouchableNavigationBar()) {
+ if (windowState != null && instance.isUntouchableNavigationBar()) {
final InsetsSourceProvider provider =
windowState.getControllableInsetProvider();
if (provider != null) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f70dec175c06..ae55a1a77873 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4575,10 +4575,22 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// at #postWindowRemoveCleanupLocked
return false;
}
+
+ // Link the fixed rotation transform to this activity since we are transferring the
+ // starting window.
+ if (fromActivity.hasFixedRotationTransform()) {
+ mDisplayContent.handleTopActivityLaunchingInDifferentOrientation(this,
+ false /* checkOpening */);
+ }
// Do not transfer if the orientation doesn't match, redraw starting window while it is
// on top will cause flicker.
- if (fromActivity.getRequestedConfigurationOrientation()
- != getRequestedConfigurationOrientation()) {
+ final int fromOrientation = fromActivity.getConfiguration().orientation;
+ final int requestedOrientation = getRequestedConfigurationOrientation();
+ if (requestedOrientation == ORIENTATION_UNDEFINED) {
+ if (fromOrientation != getConfiguration().orientation) {
+ return false;
+ }
+ } else if (fromOrientation != requestedOrientation) {
return false;
}
// In this case, the starting icon has already been displayed, so start
@@ -4592,13 +4604,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final long origId = Binder.clearCallingIdentity();
try {
- // Link the fixed rotation transform to this activity since we are transferring the
- // starting window.
- if (fromActivity.hasFixedRotationTransform()) {
- mDisplayContent.handleTopActivityLaunchingInDifferentOrientation(this,
- false /* checkOpening */);
- }
-
// Transfer the starting window over to the new token.
mStartingData = fromActivity.mStartingData;
mStartingSurface = fromActivity.mStartingSurface;
diff --git a/services/core/java/com/android/server/wm/AppCompatController.java b/services/core/java/com/android/server/wm/AppCompatController.java
index 145a3767c149..203932d4df58 100644
--- a/services/core/java/com/android/server/wm/AppCompatController.java
+++ b/services/core/java/com/android/server/wm/AppCompatController.java
@@ -76,6 +76,16 @@ class AppCompatController {
mAppCompatSizeCompatModePolicy = new AppCompatSizeCompatModePolicy(mActivityRecord,
mAppCompatOverrides);
mAllowRestrictedResizability = AppCompatUtils.asLazy(() -> {
+ // Application level.
+ try {
+ if (packageManager.getProperty(PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY,
+ mActivityRecord.packageName).getBoolean()) {
+ return true;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // Fall through.
+ }
+ // Activity level.
try {
return packageManager.getPropertyAsUser(
PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY,
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index 0b5872b3e601..93ccd74c6b23 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -32,6 +32,7 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.media.projection.IMediaProjectionManager;
+import android.media.projection.StopReason;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -226,6 +227,7 @@ final class ContentRecorder implements WindowContainerListener {
+ "size %s",
mDisplayContent.getDisplayId(), recordedContentBounds,
recordedContentOrientation, surfaceSize);
+
updateMirroredSurface(mRecordedWindowContainer.getSyncTransaction(),
recordedContentBounds, surfaceSize);
} else {
@@ -295,12 +297,12 @@ final class ContentRecorder implements WindowContainerListener {
* Ensure recording does not fall back to the display stack; ensure the recording is stopped
* and the client notified by tearing down the virtual display.
*/
- private void stopMediaProjection() {
+ private void stopMediaProjection(@StopReason int stopReason) {
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Stop MediaProjection on virtual display %d",
mDisplayContent.getDisplayId());
if (mMediaProjectionManager != null) {
- mMediaProjectionManager.stopActiveProjection();
+ mMediaProjectionManager.stopActiveProjection(stopReason);
}
}
@@ -507,7 +509,7 @@ final class ContentRecorder implements WindowContainerListener {
if (shouldExitTaskRecording) {
// Clean up the cached session first to ensure recording doesn't re-start, since
// tearing down the display will generate display events which will trickle back here.
- stopMediaProjection();
+ stopMediaProjection(StopReason.STOP_ERROR);
}
}
@@ -599,9 +601,13 @@ final class ContentRecorder implements WindowContainerListener {
mLastRecordedBounds = new Rect(recordedContentBounds);
mLastConsumingSurfaceSize.x = surfaceSize.x;
mLastConsumingSurfaceSize.y = surfaceSize.y;
- // Request to notify the client about the resize.
- mMediaProjectionManager.notifyActiveProjectionCapturedContentResized(
- mLastRecordedBounds.width(), mLastRecordedBounds.height());
+
+ // Request to notify the client about the updated bounds.
+ mMediaProjectionManager.notifyCaptureBoundsChanged(
+ mContentRecordingSession.getContentToRecord(),
+ mContentRecordingSession.getTargetUid(),
+ mLastRecordedBounds
+ );
}
/**
@@ -641,7 +647,7 @@ final class ContentRecorder implements WindowContainerListener {
clearContentRecordingSession();
// Clean up the cached session first to ensure recording doesn't re-start, since
// tearing down the display will generate display events which will trickle back here.
- stopMediaProjection();
+ stopMediaProjection(StopReason.STOP_TARGET_REMOVED);
}
// WindowContainerListener
@@ -674,10 +680,10 @@ final class ContentRecorder implements WindowContainerListener {
}
@VisibleForTesting interface MediaProjectionManagerWrapper {
- void stopActiveProjection();
- void notifyActiveProjectionCapturedContentResized(int width, int height);
+ void stopActiveProjection(@StopReason int stopReason);
void notifyActiveProjectionCapturedContentVisibilityChanged(boolean isVisible);
void notifyWindowingModeChanged(int contentToRecord, int targetUid, int windowingMode);
+ void notifyCaptureBoundsChanged(int contentToRecord, int targetUid, Rect captureBounds);
}
private static final class RemoteMediaProjectionManagerWrapper implements
@@ -691,7 +697,7 @@ final class ContentRecorder implements WindowContainerListener {
}
@Override
- public void stopActiveProjection() {
+ public void stopActiveProjection(@StopReason int stopReason) {
fetchMediaProjectionManager();
if (mIMediaProjectionManager == null) {
return;
@@ -700,7 +706,7 @@ final class ContentRecorder implements WindowContainerListener {
ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: stopping active projection for display %d",
mDisplayId);
- mIMediaProjectionManager.stopActiveProjection();
+ mIMediaProjectionManager.stopActiveProjection(stopReason);
} catch (RemoteException e) {
ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Unable to tell MediaProjectionManagerService to stop "
@@ -710,52 +716,51 @@ final class ContentRecorder implements WindowContainerListener {
}
@Override
- public void notifyActiveProjectionCapturedContentResized(int width, int height) {
+ public void notifyActiveProjectionCapturedContentVisibilityChanged(boolean isVisible) {
fetchMediaProjectionManager();
if (mIMediaProjectionManager == null) {
return;
}
try {
- mIMediaProjectionManager.notifyActiveProjectionCapturedContentResized(width,
- height);
+ mIMediaProjectionManager.notifyActiveProjectionCapturedContentVisibilityChanged(
+ isVisible);
} catch (RemoteException e) {
ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Unable to tell MediaProjectionManagerService about "
- + "resizing the active projection: %s",
+ + "visibility change on the active projection: %s",
e);
}
}
@Override
- public void notifyActiveProjectionCapturedContentVisibilityChanged(boolean isVisible) {
+ public void notifyWindowingModeChanged(int contentToRecord, int targetUid,
+ int windowingMode) {
fetchMediaProjectionManager();
if (mIMediaProjectionManager == null) {
return;
}
try {
- mIMediaProjectionManager.notifyActiveProjectionCapturedContentVisibilityChanged(
- isVisible);
+ mIMediaProjectionManager.notifyWindowingModeChanged(
+ contentToRecord, targetUid, windowingMode);
} catch (RemoteException e) {
ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Unable to tell MediaProjectionManagerService about "
- + "visibility change on the active projection: %s",
- e);
+ "Content Recording: Unable to tell log windowing mode change: %s", e);
}
}
@Override
- public void notifyWindowingModeChanged(int contentToRecord, int targetUid,
- int windowingMode) {
+ public void notifyCaptureBoundsChanged(int contentToRecord, int targetUid,
+ Rect captureBounds) {
fetchMediaProjectionManager();
if (mIMediaProjectionManager == null) {
return;
}
try {
- mIMediaProjectionManager.notifyWindowingModeChanged(
- contentToRecord, targetUid, windowingMode);
+ mIMediaProjectionManager.notifyCaptureBoundsChanged(
+ contentToRecord, targetUid, captureBounds);
} catch (RemoteException e) {
ProtoLog.e(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Unable to tell log windowing mode change: %s", e);
+ "Content Recording: Unable to tell log bounds change: %s", e);
}
}
diff --git a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
index 6f8c17a9ac75..4e79e377a2a3 100644
--- a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
+++ b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
@@ -403,6 +403,7 @@ class DeferredDisplayUpdater {
|| first.renderFrameRate != second.renderFrameRate
|| first.hasArrSupport != second.hasArrSupport
|| !Objects.equals(first.frameRateCategoryRate, second.frameRateCategoryRate)
+ || !Arrays.equals(first.supportedRefreshRates, second.supportedRefreshRates)
|| first.defaultModeId != second.defaultModeId
|| first.userPreferredModeId != second.userPreferredModeId
|| !Arrays.equals(first.supportedModes, second.supportedModes)
diff --git a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
index c8cb62132b4c..43855aa3d247 100644
--- a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
+++ b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
@@ -196,10 +196,11 @@ public class DesktopAppCompatAspectRatioPolicy {
if (!aspectRatioOverrides.shouldOverrideMinAspectRatio()
&& !AppCompatCameraPolicy.shouldOverrideMinAspectRatioForCamera(mActivityRecord)) {
- if (mActivityRecord.isUniversalResizeable()) {
+ final float minAspectRatio = info.getMinAspectRatio();
+ if (minAspectRatio == 0 || mActivityRecord.isUniversalResizeable()) {
return 0;
}
- return info.getMinAspectRatio();
+ return minAspectRatio;
}
if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY)
@@ -242,10 +243,11 @@ public class DesktopAppCompatAspectRatioPolicy {
if (mTransparentPolicy.isRunning()) {
return mTransparentPolicy.getInheritedMaxAspectRatio();
}
- if (mActivityRecord.isUniversalResizeable()) {
+ final float maxAspectRatio = mActivityRecord.info.getMaxAspectRatio();
+ if (maxAspectRatio == 0 || mActivityRecord.isUniversalResizeable()) {
return 0;
}
- return mActivityRecord.info.getMaxAspectRatio();
+ return maxAspectRatio;
}
/**
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e9e550e72a00..9a33df13bb6a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5502,14 +5502,18 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// Attach the SystemUiContext to this DisplayContent the get latest configuration.
// Note that the SystemUiContext will be removed automatically if this DisplayContent
// is detached.
- final WindowProcessController wpc = mAtmService.getProcessController(
- getDisplayUiContext().getIApplicationThread());
- mWmService.mWindowContextListenerController.registerWindowContainerListener(
- wpc, getDisplayUiContext().getWindowContextToken(), this,
- INVALID_WINDOW_TYPE, null /* options */);
+ registerSystemUiContext();
}
}
+ private void registerSystemUiContext() {
+ final WindowProcessController wpc = mAtmService.getProcessController(
+ getDisplayUiContext().getIApplicationThread());
+ mWmService.mWindowContextListenerController.registerWindowContainerListener(
+ wpc, getDisplayUiContext().getWindowContextToken(), this,
+ INVALID_WINDOW_TYPE, null /* options */);
+ }
+
@Override
void assignChildLayers(SurfaceControl.Transaction t) {
assignRelativeLayerForIme(t, false /* forceUpdate */);
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 4cf1fb400fe7..df209ff4cf50 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -485,6 +485,9 @@ public class DisplayRotation {
if (isDefaultDisplay) {
updateOrientationListenerLw();
}
+ } else if (mCompatPolicyForImmersiveApps != null
+ && mCompatPolicyForImmersiveApps.deferOrientationUpdate()) {
+ return false;
}
return updateRotationUnchecked(forceUpdate);
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java
index 094434d07cfe..046ed614dc19 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicy.java
@@ -17,10 +17,13 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
+import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Configuration.Orientation;
@@ -66,6 +69,37 @@ final class DisplayRotationImmersiveAppCompatPolicy {
}
/**
+ * Returns {@code true} if the orientation update should be skipped and it will update when
+ * transition is done. This is to keep the orientation which was preserved by
+ * {@link #isRotationLockEnforced} from being changed by a transient launch (i.e. recents).
+ */
+ boolean deferOrientationUpdate() {
+ if (mDisplayRotation.getUserRotation() != USER_ROTATION_FREE
+ || mDisplayRotation.getLastOrientation() != SCREEN_ORIENTATION_UNSPECIFIED) {
+ return false;
+ }
+ final WindowOrientationListener orientationListener =
+ mDisplayRotation.getOrientationListener();
+ if (orientationListener == null
+ || orientationListener.getProposedRotation() == mDisplayRotation.getRotation()) {
+ return false;
+ }
+ // The above conditions mean that isRotationLockEnforced might have taken effect:
+ // Auto-rotation is enabled and the proposed rotation is not applied.
+ // Then the update should defer until the transition idle to avoid disturbing animation.
+ if (!mDisplayContent.mTransitionController.hasTransientLaunch(mDisplayContent)) {
+ return false;
+ }
+ mDisplayContent.mTransitionController.mStateValidators.add(() -> {
+ if (!isRotationLockEnforcedLocked(orientationListener.getProposedRotation())) {
+ mDisplayContent.mWmService.updateRotation(false /* alwaysSendConfiguration */,
+ false /* forceRelayout */);
+ }
+ });
+ return true;
+ }
+
+ /**
* Decides whether it is necessary to lock screen rotation, preventing auto rotation, based on
* the top activity configuration and proposed screen rotation.
*
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index f0e12fec3107..27f82d90fdac 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -495,11 +495,18 @@ class RecentTasks {
mTaskNotificationController.notifyTaskListUpdated();
}
- private void notifyTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess) {
+ private void notifyTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess,
+ boolean removedForAddTask) {
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onRecentTaskRemoved(task, wasTrimmed, killProcess);
}
mTaskNotificationController.notifyTaskListUpdated();
+ if (removedForAddTask) {
+ mTaskNotificationController.notifyRecentTaskRemovedForAddTask(task.mTaskId);
+ }
+ }
+ private void notifyTaskRemoved(Task task, boolean wasTrimmed, boolean killProcess) {
+ notifyTaskRemoved(task, wasTrimmed, killProcess, false /* removedForAddTask */);
}
/**
@@ -1635,7 +1642,8 @@ class RecentTasks {
// from becoming dangling.
mHiddenTasks.add(0, removedTask);
}
- notifyTaskRemoved(removedTask, false /* wasTrimmed */, false /* killProcess */);
+ notifyTaskRemoved(removedTask, false /* wasTrimmed */, false /* killProcess */,
+ true /* removedForAddTask */);
if (DEBUG_RECENTS_TRIM_TASKS) {
Slog.d(TAG, "Trimming task=" + removedTask
+ " for addition of task=" + task);
diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java
index 70b214cc71b5..88e534351e2e 100644
--- a/services/core/java/com/android/server/wm/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java
@@ -361,10 +361,13 @@ public class SafeActivityOptions {
}
// If launched from bubble is specified, then ensure that the caller is system or sysui.
- if (options.getLaunchedFromBubble() && !isSystemOrSystemUI(callingPid, callingUid)) {
+ if ((options.getLaunchedFromBubble() || options.getTaskAlwaysOnTop())
+ && !isSystemOrSystemUI(callingPid, callingUid)) {
final String msg = "Permission Denial: starting " + getIntentString(intent)
+ " from " + callerApp + " (pid=" + callingPid
- + ", uid=" + callingUid + ") with launchedFromBubble=true";
+ + ", uid=" + callingUid + ") with"
+ + (options.getLaunchedFromBubble() ? " launchedFromBubble=true" : "")
+ + (options.getTaskAlwaysOnTop() ? " taskAlwaysOnTop=true" : "");
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 586f3c35c0c4..c3649fe98056 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -62,6 +62,8 @@ class TaskChangeNotificationController {
private static final int NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG = 27;
private static final int NOTIFY_LOCK_TASK_MODE_CHANGED_MSG = 28;
private static final int NOTIFY_TASK_SNAPSHOT_INVALIDATED_LISTENERS_MSG = 29;
+ private static final int NOTIFY_RECENT_TASK_REMOVED_FOR_ADD_TASK_LISTENERS_MSG = 30;
+
// Delay in notifying task stack change listeners (in millis)
private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -167,6 +169,10 @@ class TaskChangeNotificationController {
l.onRecentTaskListFrozenChanged(m.arg1 != 0);
};
+ private final TaskStackConsumer mNotifyRecentTaskRemovedForAddTask = (l, m) -> {
+ l.onRecentTaskRemovedForAddTask(m.arg1);
+ };
+
private final TaskStackConsumer mNotifyTaskFocusChanged = (l, m) -> {
l.onTaskFocusChanged(m.arg1, m.arg2 != 0);
};
@@ -261,6 +267,9 @@ class TaskChangeNotificationController {
case NOTIFY_TASK_LIST_FROZEN_UNFROZEN_MSG:
forAllRemoteListeners(mNotifyTaskListFrozen, msg);
break;
+ case NOTIFY_RECENT_TASK_REMOVED_FOR_ADD_TASK_LISTENERS_MSG:
+ forAllRemoteListeners(mNotifyRecentTaskRemovedForAddTask, msg);
+ break;
case NOTIFY_TASK_FOCUS_CHANGED_MSG:
forAllRemoteListeners(mNotifyTaskFocusChanged, msg);
break;
@@ -541,6 +550,15 @@ class TaskChangeNotificationController {
msg.sendToTarget();
}
+ /** Called when a task is removed from the recent tasks list. */
+ void notifyRecentTaskRemovedForAddTask(int taskId) {
+ final Message msg = mHandler.obtainMessage(
+ NOTIFY_RECENT_TASK_REMOVED_FOR_ADD_TASK_LISTENERS_MSG, taskId,
+ 0 /* unused */);
+ forAllLocalListeners(mNotifyRecentTaskRemovedForAddTask, msg);
+ msg.sendToTarget();
+ }
+
/** @see ITaskStackListener#onTaskFocusChanged(int, boolean) */
void notifyTaskFocusChanged(int taskId, boolean focused) {
final Message msg = mHandler.obtainMessage(NOTIFY_TASK_FOCUS_CHANGED_MSG,
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index ce032b4f7f9a..c77b1d9a7bcf 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -46,7 +46,6 @@ import android.view.RemoteAnimationTarget;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
-import android.view.WindowInfo;
import android.view.WindowManager.DisplayImePolicy;
import android.view.inputmethod.ImeTracker;
import android.window.ScreenCapture;
@@ -158,26 +157,8 @@ public abstract class WindowManagerInternal {
* accessibility changed.
*/
public interface WindowsForAccessibilityCallback {
-
- /**
- * Called when the windows for accessibility changed. This is called if
- * {@link com.android.server.accessibility.Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2} is
- * false.
- *
- * @param forceSend Send the windows for accessibility even if they haven't changed.
- * @param topFocusedDisplayId The display Id which has the top focused window.
- * @param topFocusedWindowToken The window token of top focused window.
- * @param windows The windows for accessibility.
- */
- void onWindowsForAccessibilityChanged(boolean forceSend, int topFocusedDisplayId,
- IBinder topFocusedWindowToken, @NonNull List<WindowInfo> windows);
-
/**
- * Called when the windows for accessibility changed. This is called if
- * {@link com.android.server.accessibility.Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2} is
- * true.
- * TODO(b/322444245): Remove screenSize parameter by getting it from
- * DisplayManager#getDisplay(int).getRealSize() on the a11y side.
+ * Called when the windows for accessibility changed.
*
* @param forceSend Send the windows for accessibility even if they haven't changed.
* @param topFocusedDisplayId The display Id which has the top focused window.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8268cae12e3d..a0c0b9836507 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3030,8 +3030,8 @@ public class WindowManagerService extends IWindowManager.Stub
mWindowContextListenerController.unregisterWindowContainerListener(clientToken);
- final WindowToken token = wc.asWindowToken();
- if (token != null && token.isFromClient()) {
+ final WindowToken token = wc != null ? wc.asWindowToken() : null;
+ if (token != null && token.isFromClient() && token.getDisplayContent() != null) {
removeWindowToken(token.token, token.getDisplayContent().getDisplayId());
}
}
@@ -10314,7 +10314,7 @@ public class WindowManagerService extends IWindowManager.Stub
mH.post(() -> {
Toast.makeText(mContext, Looper.getMainLooper(),
mContext.getString(R.string.screen_not_shared_sensitive_content),
- Toast.LENGTH_SHORT)
+ Toast.LENGTH_LONG)
.show();
});
// If blocked due to notification protection (null window token) log protection applied
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index eaa3a37d5bf3..4c0cee404b68 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -38,7 +38,6 @@ cc_library_static {
"com_android_server_adb_AdbDebuggingManager.cpp",
"com_android_server_am_BatteryStatsService.cpp",
"com_android_server_biometrics_SurfaceToNativeHandleConverter.cpp",
- "com_android_server_ConsumerIrService.cpp",
"com_android_server_companion_virtual_InputController.cpp",
"com_android_server_companion_virtual_VirtualDeviceImpl.cpp",
"com_android_server_devicepolicy_CryptoTestHelper.cpp",
@@ -63,7 +62,6 @@ cc_library_static {
"com_android_server_SystemServer.cpp",
"com_android_server_tv_TvUinputBridge.cpp",
"com_android_server_tv_TvInputHal.cpp",
- "com_android_server_vr_VrManagerService.cpp",
"com_android_server_UsbAlsaJackDetector.cpp",
"com_android_server_UsbAlsaMidiDevice.cpp",
"com_android_server_UsbDeviceManager.cpp",
@@ -75,14 +73,13 @@ cc_library_static {
"com_android_server_am_LowMemDetector.cpp",
"com_android_server_pm_PackageManagerShellCommandDataLoader.cpp",
"com_android_server_sensor_SensorService.cpp",
- "com_android_server_utils_LazyJniRegistrar.cpp",
"com_android_server_wm_TaskFpsCallbackController.cpp",
"onload.cpp",
":lib_cachedAppOptimizer_native",
":lib_freezer_native",
- ":lib_gameManagerService_native",
":lib_oomConnection_native",
":lib_anrTimer_native",
+ ":lib_lazilyRegisteredServices_native",
],
include_dirs: [
@@ -248,13 +245,6 @@ filegroup {
}
filegroup {
- name: "lib_gameManagerService_native",
- srcs: [
- "com_android_server_app_GameManagerService.cpp",
- ],
-}
-
-filegroup {
name: "lib_oomConnection_native",
srcs: ["com_android_server_am_OomConnection.cpp"],
}
@@ -265,3 +255,13 @@ filegroup {
"com_android_server_utils_AnrTimer.cpp",
],
}
+
+filegroup {
+ name: "lib_lazilyRegisteredServices_native",
+ srcs: [
+ "com_android_server_ConsumerIrService.cpp",
+ "com_android_server_app_GameManagerService.cpp",
+ "com_android_server_utils_LazyJniRegistrar.cpp",
+ "com_android_server_vr_VrManagerService.cpp",
+ ],
+}
diff --git a/services/core/jni/com_android_server_utils_LazyJniRegistrar.cpp b/services/core/jni/com_android_server_utils_LazyJniRegistrar.cpp
index ad7781e3b8b5..0c0f8b02279b 100644
--- a/services/core/jni/com_android_server_utils_LazyJniRegistrar.cpp
+++ b/services/core/jni/com_android_server_utils_LazyJniRegistrar.cpp
@@ -22,6 +22,7 @@ namespace android {
// Forward declared per-class registration methods.
int register_android_server_ConsumerIrService(JNIEnv* env);
+int register_android_server_app_GameManagerService(JNIEnv* env);
int register_android_server_vr_VrManagerService(JNIEnv* env);
namespace {
@@ -33,12 +34,17 @@ void registerConsumerIrService(JNIEnv* env, jclass) {
register_android_server_ConsumerIrService(env);
}
+void registerGameManagerService(JNIEnv* env, jclass) {
+ register_android_server_app_GameManagerService(env);
+}
+
void registerVrManagerService(JNIEnv* env, jclass) {
register_android_server_vr_VrManagerService(env);
}
static const JNINativeMethod sJniRegistrarMethods[] = {
{"registerConsumerIrService", "()V", (void*)registerConsumerIrService},
+ {"registerGameManagerService", "()V", (void*)registerGameManagerService},
{"registerVrManagerService", "()V", (void*)registerVrManagerService},
};
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index c170ae99da04..df37ec3ef037 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -65,7 +65,6 @@ int register_android_server_stats_pull_StatsPullAtomService(JNIEnv* env);
int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env);
int register_android_server_companion_virtual_InputController(JNIEnv* env);
int register_android_server_companion_virtual_VirtualDeviceImpl(JNIEnv* env);
-int register_android_server_app_GameManagerService(JNIEnv* env);
int register_com_android_server_wm_TaskFpsCallbackController(JNIEnv* env);
int register_com_android_server_display_DisplayControl(JNIEnv* env);
int register_com_android_server_SystemClockTime(JNIEnv* env);
@@ -131,7 +130,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_sensor_SensorService(vm, env);
register_android_server_companion_virtual_InputController(env);
register_android_server_companion_virtual_VirtualDeviceImpl(env);
- register_android_server_app_GameManagerService(env);
register_com_android_server_wm_TaskFpsCallbackController(env);
register_com_android_server_display_DisplayControl(env);
register_com_android_server_SystemClockTime(env);
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index e307e529a40b..228e32e98cc7 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -70,6 +70,7 @@ public final class ProfcollectForwardingService extends SystemService {
private int mUsageSetting;
private boolean mUploadEnabled;
+ private static boolean sVerityEnforced;
private boolean mAdbActive;
private IProfCollectd mIProfcollect;
@@ -117,6 +118,13 @@ public final class ProfcollectForwardingService extends SystemService {
mUsageSetting = -1;
}
+ // Check verity, disable profile upload if not enforced.
+ final String verityMode = SystemProperties.get("ro.boot.veritymode");
+ sVerityEnforced = verityMode.equals("enforcing");
+ if (!sVerityEnforced) {
+ Log.d(LOG_TAG, "verity is not enforced: " + verityMode);
+ }
+
mUploadEnabled =
context.getResources().getBoolean(R.bool.config_profcollectReportUploaderEnabled);
@@ -373,6 +381,10 @@ public final class ProfcollectForwardingService extends SystemService {
Log.i(LOG_TAG, "Upload is not enabled.");
return;
}
+ if (!sVerityEnforced) {
+ Log.i(LOG_TAG, "Verity is not enforced.");
+ return;
+ }
Intent intent = new Intent()
.setPackage("com.android.shell")
.setAction("com.android.shell.action.PROFCOLLECT_UPLOAD")
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 759976f79371..47e96d378149 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -17,6 +17,7 @@
package com.android.server.display;
import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY;
+import static android.Manifest.permission.ADD_MIRROR_DISPLAY;
import static android.Manifest.permission.ADD_TRUSTED_DISPLAY;
import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT;
import static android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS;
@@ -122,6 +123,7 @@ import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserManager;
import android.os.test.FakePermissionEnforcer;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
@@ -1388,6 +1390,7 @@ public class DisplayManagerServiceTest {
* Tests that it's not allowed to create an auto-mirror virtual display without
* CAPTURE_VIDEO_OUTPUT permission or a virtual device that can mirror displays
*/
+ @EnableFlags(android.companion.virtualdevice.flags.Flags.FLAG_ENABLE_LIMITED_VDM_ROLE)
@Test
public void createAutoMirrorDisplay_withoutPermissionOrAllowedVirtualDevice_throwsException()
throws Exception {
@@ -1397,7 +1400,8 @@ public class DisplayManagerServiceTest {
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
when(virtualDevice.getDeviceId()).thenReturn(1);
- when(virtualDevice.canCreateMirrorDisplays()).thenReturn(false);
+ when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
when(mContext.checkCallingPermission(CAPTURE_VIDEO_OUTPUT)).thenReturn(
PackageManager.PERMISSION_DENIED);
@@ -1428,7 +1432,8 @@ public class DisplayManagerServiceTest {
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
when(virtualDevice.getDeviceId()).thenReturn(1);
- when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true);
+ when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
// Create an auto-mirror virtual display using a virtual device.
@@ -1461,7 +1466,8 @@ public class DisplayManagerServiceTest {
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
when(virtualDevice.getDeviceId()).thenReturn(1);
- when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true);
+ when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
// Create an auto-mirror virtual display using a virtual device.
@@ -1528,7 +1534,8 @@ public class DisplayManagerServiceTest {
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
when(virtualDevice.getDeviceId()).thenReturn(1);
- when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true);
+ when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
when(mContext.checkCallingPermission(ADD_ALWAYS_UNLOCKED_DISPLAY))
.thenReturn(PackageManager.PERMISSION_GRANTED);
@@ -1564,7 +1571,8 @@ public class DisplayManagerServiceTest {
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
when(virtualDevice.getDeviceId()).thenReturn(1);
- when(virtualDevice.canCreateMirrorDisplays()).thenReturn(true);
+ when(mContext.checkCallingPermission(ADD_MIRROR_DISPLAY))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
when(mIVirtualDeviceManager.isValidVirtualDeviceId(1)).thenReturn(true);
// Create an auto-mirror virtual display using a virtual device.
diff --git a/services/tests/mockingservicestests/jni/Android.bp b/services/tests/mockingservicestests/jni/Android.bp
index 00543a8a9871..94d4b9522d60 100644
--- a/services/tests/mockingservicestests/jni/Android.bp
+++ b/services/tests/mockingservicestests/jni/Android.bp
@@ -22,8 +22,8 @@ cc_library_shared {
srcs: [
":lib_cachedAppOptimizer_native",
":lib_freezer_native",
- ":lib_gameManagerService_native",
":lib_oomConnection_native",
+ ":lib_lazilyRegisteredServices_native",
"onload.cpp",
],
@@ -54,6 +54,8 @@ cc_library_shared {
"android.hardware.graphics.bufferqueue@2.0",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@4.0",
+ "android.hardware.ir@1.0",
+ "android.hardware.vr@1.0",
"android.hidl.token@1.0-utils",
],
}
diff --git a/services/tests/mockingservicestests/jni/onload.cpp b/services/tests/mockingservicestests/jni/onload.cpp
index cb246d15fce8..9b4c8178b092 100644
--- a/services/tests/mockingservicestests/jni/onload.cpp
+++ b/services/tests/mockingservicestests/jni/onload.cpp
@@ -26,8 +26,8 @@
namespace android {
int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
int register_android_server_am_Freezer(JNIEnv* env);
-int register_android_server_app_GameManagerService(JNIEnv* env);
int register_android_server_am_OomConnection(JNIEnv* env);
+int register_android_server_utils_LazyJniRegistrar(JNIEnv* env);
};
using namespace android;
@@ -44,7 +44,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
ALOG_ASSERT(env, "Could not retrieve the env!");
register_android_server_am_CachedAppOptimizer(env);
register_android_server_am_Freezer(env);
- register_android_server_app_GameManagerService(env);
register_android_server_am_OomConnection(env);
+ register_android_server_utils_LazyJniRegistrar(env);
return JNI_VERSION_1_4;
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index a9569b4096ff..1efe4707fc11 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -105,6 +105,7 @@ import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.ArrayMap;
@@ -3260,6 +3261,24 @@ public class MockingOomAdjusterTests {
"cch-empty");
}
+ @SuppressWarnings("GuardedBy")
+ @Test
+ @EnableFlags(Flags.FLAG_FIX_APPLY_OOMADJ_ORDER)
+ public void testUpdateOomAdj_ApplyOomAdjInCorrectOrder() {
+ final int numberOfApps = 5;
+ final ProcessRecord[] apps = new ProcessRecord[numberOfApps];
+ for (int i = 0; i < numberOfApps; i++) {
+ apps[i] = spy(makeDefaultProcessRecord(MOCKAPP_PID + i, MOCKAPP_UID + i,
+ MOCKAPP_PROCESSNAME + i, MOCKAPP_PACKAGENAME + i, true));
+ }
+ updateOomAdj(apps);
+ for (int i = 1; i < numberOfApps; i++) {
+ final int pre = mInjector.mSetOomAdjAppliedAt.get(apps[i - 1].mPid);
+ final int cur = mInjector.mSetOomAdjAppliedAt.get(apps[i].mPid);
+ assertTrue("setOomAdj is called in wrong order", pre < cur);
+ }
+ }
+
private ProcessRecord makeDefaultProcessRecord(int pid, int uid, String processName,
String packageName, boolean hasShownUi) {
return new ProcessRecordBuilder(pid, uid, processName, packageName).setHasShownUi(
@@ -3589,9 +3608,16 @@ public class MockingOomAdjusterTests {
long mTimeOffsetMillis = 0;
private SparseIntArray mLastSetOomAdj = new SparseIntArray();
+ // A sequence number that increases every time setOomAdj is called
+ int mLastAppliedAt = 0;
+ // Holds the last sequence number setOomAdj is called for a pid
+ private SparseIntArray mSetOomAdjAppliedAt = new SparseIntArray();
+
void reset() {
mTimeOffsetMillis = 0;
mLastSetOomAdj.clear();
+ mLastAppliedAt = 0;
+ mSetOomAdjAppliedAt.clear();
}
void jumpUptimeAheadTo(long uptimeMillis) {
@@ -3616,6 +3642,7 @@ public class MockingOomAdjusterTests {
final int pid = proc.getPid();
if (pid <= 0) continue;
mLastSetOomAdj.put(pid, proc.mState.getCurAdj());
+ mSetOomAdjAppliedAt.put(pid, mLastAppliedAt++);
}
}
@@ -3623,6 +3650,7 @@ public class MockingOomAdjusterTests {
void setOomAdj(int pid, int uid, int adj) {
if (pid <= 0) return;
mLastSetOomAdj.put(pid, adj);
+ mSetOomAdjAppliedAt.put(pid, mLastAppliedAt++);
}
@Override
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java
index 769f071e3ddc..405024cc0e34 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -134,7 +134,7 @@ public class ApexManagerTest {
mMockSystem.system().validateFinalState();
mInstallPackageHelper = new InstallPackageHelper(mPmService, mock(AppDataHelper.class),
mock(RemovePackageHelper.class), mock(DeletePackageHelper.class),
- mock(BroadcastHelper.class));
+ mock(BroadcastHelper.class), mock(InstallDependencyHelper.class));
}
@NonNull
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java
index 20ac0781e2ed..0304a74f7654 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/InstallDependencyHelperTest.java
@@ -79,12 +79,14 @@ public class InstallDependencyHelperTest {
@Mock private SharedLibrariesImpl mSharedLibraries;
@Mock private Context mContext;
@Mock private Computer mComputer;
+ @Mock private PackageInstallerService mPackageInstallerService;
private InstallDependencyHelper mInstallDependencyHelper;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mInstallDependencyHelper = new InstallDependencyHelper(mContext, mSharedLibraries);
+ mInstallDependencyHelper = new InstallDependencyHelper(mContext, mSharedLibraries,
+ mPackageInstallerService);
}
@Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 0a6edf1b9831..b53dbc834351 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -218,6 +218,8 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
val handler = TestHandler(null)
val defaultAppProvider: DefaultAppProvider = mock()
val backgroundHandler = TestHandler(null)
+ val packageInstallerService: PackageInstallerService = mock()
+ val installDependencyHelper: InstallDependencyHelper = mock()
val updateOwnershipHelper: UpdateOwnershipHelper = mock()
}
@@ -306,6 +308,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
whenever(mocks.injector.handler) { mocks.handler }
whenever(mocks.injector.defaultAppProvider) { mocks.defaultAppProvider }
whenever(mocks.injector.backgroundHandler) { mocks.backgroundHandler }
+ whenever(mocks.injector.packageInstallerService) { mocks.packageInstallerService }
whenever(mocks.injector.updateOwnershipHelper) { mocks.updateOwnershipHelper }
whenever(mocks.injector.getSystemService(AppOpsManager::class.java)) { mocks.appOpsManager }
wheneverStatic { SystemConfig.getInstance() }.thenReturn(mocks.systemConfig)
@@ -332,6 +335,8 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
DEVICE_PROVISIONING_PACKAGE_NAME
}
whenever(mocks.apexManager.activeApexInfos).thenReturn(DEFAULT_ACTIVE_APEX_INFO_LIST)
+ whenever(mocks.packageInstallerService.installDependencyHelper).thenReturn(
+ mocks.installDependencyHelper)
whenever(mocks.settings.packagesLocked).thenReturn(mSettingsMap)
whenever(mocks.settings.internalVersion).thenReturn(DEFAULT_VERSION_INFO)
whenever(mocks.settings.keySetManagerService).thenReturn(mocks.keySetManagerService)
diff --git a/services/tests/servicestests/jni/Android.bp b/services/tests/servicestests/jni/Android.bp
index 0a3103722796..e738c19cc545 100644
--- a/services/tests/servicestests/jni/Android.bp
+++ b/services/tests/servicestests/jni/Android.bp
@@ -22,9 +22,9 @@ cc_library_shared {
srcs: [
":lib_cachedAppOptimizer_native",
":lib_freezer_native",
- ":lib_gameManagerService_native",
":lib_oomConnection_native",
":lib_anrTimer_native",
+ ":lib_lazilyRegisteredServices_native",
"onload.cpp",
],
@@ -55,6 +55,8 @@ cc_library_shared {
"android.hardware.graphics.bufferqueue@2.0",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@4.0",
+ "android.hardware.ir@1.0",
+ "android.hardware.vr@1.0",
"android.hidl.token@1.0-utils",
],
}
diff --git a/services/tests/servicestests/jni/onload.cpp b/services/tests/servicestests/jni/onload.cpp
index 25487c5aabbe..ad979c62f40e 100644
--- a/services/tests/servicestests/jni/onload.cpp
+++ b/services/tests/servicestests/jni/onload.cpp
@@ -25,9 +25,9 @@
namespace android {
int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
-int register_android_server_app_GameManagerService(JNIEnv* env);
int register_android_server_am_OomConnection(JNIEnv* env);
int register_android_server_utils_AnrTimer(JNIEnv *env);
+int register_android_server_utils_LazyJniRegistrar(JNIEnv* env);
};
using namespace android;
@@ -43,8 +43,8 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
}
ALOG_ASSERT(env, "Could not retrieve the env!");
register_android_server_am_CachedAppOptimizer(env);
- register_android_server_app_GameManagerService(env);
register_android_server_am_OomConnection(env);
register_android_server_utils_AnrTimer(env);
+ register_android_server_utils_LazyJniRegistrar(env);
return JNI_VERSION_1_4;
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index 403930d96a12..2ae31ad618d6 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -18,20 +18,24 @@ package com.android.server.accessibility;
import static com.android.server.accessibility.AbstractAccessibilityServiceConnection.DISPLAY_TYPE_DEFAULT;
import static com.android.server.accessibility.AccessibilityWindowManagerTest.DisplayIdMatcher.displayId;
+import static com.android.server.accessibility.AccessibilityWindowManagerTest.EventWindowIdMatcher.eventWindowId;
import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowChangesMatcher.a11yWindowChanges;
-import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowIdMatcher.a11yWindowId;
+import static com.android.server.accessibility.AccessibilityWindowManagerTest.WindowIdMatcher.windowId;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -42,14 +46,13 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.annotation.Nullable;
+import android.graphics.Point;
+import android.graphics.Rect;
import android.graphics.Region;
import android.os.IBinder;
import android.os.LocaleList;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.platform.test.annotations.RequiresFlagsDisabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.SparseArray;
import android.view.Display;
import android.view.IWindow;
@@ -63,6 +66,7 @@ import android.view.accessibility.IAccessibilityInteractionConnection;
import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
import com.android.server.accessibility.test.MessageCapturingHandler;
+import com.android.server.wm.AccessibilityWindowsPopulator.AccessibilityWindow;
import com.android.server.wm.WindowManagerInternal;
import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback;
@@ -70,7 +74,6 @@ import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
@@ -81,17 +84,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-// This test verifies deprecated codepath. Probably changing this file means
-// AccessibilityWindowManagerWithAccessibilityWindowTest also needs to be updated.
-// LINT.IfChange
-
/**
- * Tests for the AccessibilityWindowManager with Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2
- * enabled.
- * TODO(b/322444245): Merge with AccessibilityWindowManagerWithAccessibilityWindowTest
- * after completing the flag migration.
+ * Tests for the AccessibilityWindowManager.
*/
-@RequiresFlagsDisabled(Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2)
public class AccessibilityWindowManagerTest {
private static final String PACKAGE_NAME = "com.android.server.accessibility";
private static final boolean FORCE_SEND = true;
@@ -122,9 +117,8 @@ public class AccessibilityWindowManagerTest {
// List of window token, mapping from windowId -> window token.
private final SparseArray<IWindow> mA11yWindowTokens = new SparseArray<>();
- // List of window info lists, mapping from displayId -> window info lists.
- private final SparseArray<ArrayList<WindowInfo>> mWindowInfos =
- new SparseArray<>();
+ // List of window info lists, mapping from displayId -> a11y window lists.
+ private final SparseArray<ArrayList<AccessibilityWindow>> mWindows = new SparseArray<>();
// List of callback, mapping from displayId -> callback.
private final SparseArray<WindowsForAccessibilityCallback> mCallbackOfWindows =
new SparseArray<>();
@@ -134,6 +128,13 @@ public class AccessibilityWindowManagerTest {
private final MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
+ // This maps displayId -> next region offset.
+ // Touchable region must have un-occluded area so that it's exposed to a11y services.
+ // This offset can be used as left and top of new region so that top-left of each region are
+ // kept visible.
+ // It's expected to be incremented by some amount everytime the value is used.
+ private final SparseArray<Integer> mNextRegionOffsets = new SparseArray<>();
+
@Mock private WindowManagerInternal mMockWindowManagerInternal;
@Mock private AccessibilityWindowManager.AccessibilityEventSender mMockA11yEventSender;
@Mock private AccessibilitySecurityPolicy mMockA11ySecurityPolicy;
@@ -144,9 +145,6 @@ public class AccessibilityWindowManagerTest {
@Mock private IBinder mMockEmbeddedToken;
@Mock private IBinder mMockInvalidToken;
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
@Before
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
@@ -159,7 +157,7 @@ public class AccessibilityWindowManagerTest {
anyString(), anyInt(), anyInt(), anyInt())).thenReturn(PACKAGE_NAME);
doAnswer((invocation) -> {
- onWindowsForAccessibilityChanged(invocation.getArgument(0), false);
+ onAccessibilityWindowsChanged(invocation.getArgument(0), false);
return null;
}).when(mMockWindowManagerInternal).computeWindowsForAccessibility(anyInt());
@@ -173,7 +171,7 @@ public class AccessibilityWindowManagerTest {
// as top focused display before each testing starts.
startTrackingPerDisplay(Display.DEFAULT_DISPLAY);
- // AccessibilityEventSender is invoked during onWindowsForAccessibilityChanged.
+ // AccessibilityEventSender is invoked during onAccessibilityWindowsChanged.
// Resets it for mockito verify of further test case.
Mockito.reset(mMockA11yEventSender);
@@ -237,19 +235,18 @@ public class AccessibilityWindowManagerTest {
@Test
public void onWindowsChanged_duringTouchInteractAndFocusChange_shouldChangeActiveWindow() {
final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
- WindowInfo focusedWindowInfo =
- mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX);
+ final WindowInfo focusedWindowInfo =
+ mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
assertEquals(activeWindowId, mA11yWindowManager.findWindowIdLocked(
USER_SYSTEM_ID, focusedWindowInfo.token));
focusedWindowInfo.focused = false;
- focusedWindowInfo =
- mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX + 1);
- focusedWindowInfo.focused = true;
+ mWindows.get(Display.DEFAULT_DISPLAY).get(
+ DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().focused = true;
mA11yWindowManager.onTouchInteractionStart();
setTopFocusedWindowAndDisplay(Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX + 1);
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
}
@@ -273,7 +270,7 @@ public class AccessibilityWindowManagerTest {
changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
DEFAULT_FOCUSED_INDEX + 1, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
- onWindowsForAccessibilityChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
+ onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
// The active window should not be changed.
assertEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
// The top focused window should not be changed.
@@ -301,8 +298,8 @@ public class AccessibilityWindowManagerTest {
changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
DEFAULT_FOCUSED_INDEX, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
- onWindowsForAccessibilityChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+ onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
// The active window should be changed.
assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
// The top focused window should be changed.
@@ -312,53 +309,181 @@ public class AccessibilityWindowManagerTest {
@Test
public void onWindowsChanged_shouldReportCorrectLayer() {
- // AccessibilityWindowManager#onWindowsForAccessibilityChanged already invoked in setup.
+ // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
List<AccessibilityWindowInfo> a11yWindows =
mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
for (int i = 0; i < a11yWindows.size(); i++) {
final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
- final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(i);
- assertThat(mWindowInfos.get(Display.DEFAULT_DISPLAY).size() - windowInfo.layer - 1,
+ assertThat(mWindows.get(Display.DEFAULT_DISPLAY).size() - i - 1,
is(a11yWindow.getLayer()));
}
}
@Test
public void onWindowsChanged_shouldReportCorrectOrder() {
- // AccessibilityWindowManager#onWindowsForAccessibilityChanged already invoked in setup.
+ // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
List<AccessibilityWindowInfo> a11yWindows =
mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
for (int i = 0; i < a11yWindows.size(); i++) {
final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
final IBinder windowToken = mA11yWindowManager
.getWindowTokenForUserAndWindowIdLocked(USER_SYSTEM_ID, a11yWindow.getId());
- final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(i);
+ final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY)
+ .get(i).getWindowInfo();
assertThat(windowToken, is(windowInfo.token));
}
}
@Test
- public void onWindowsChangedAndForceSend_shouldUpdateWindows() {
- final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
- final int correctLayer =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer();
- windowInfo.layer += 1;
+ public void onWindowsChanged_shouldNotReportNonTouchableWindow() {
+ final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+ when(window.isTouchable()).thenReturn(false);
+ final int windowId = mA11yWindowManager.findWindowIdLocked(
+ USER_SYSTEM_ID, window.getWindowInfo().token);
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+ final List<AccessibilityWindowInfo> a11yWindows =
+ mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ assertThat(a11yWindows, not(hasItem(windowId(windowId))));
+ }
+
+ @Test
+ public void onWindowsChanged_shouldReportFocusedNonTouchableWindow() {
+ final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
+ DEFAULT_FOCUSED_INDEX);
+ when(window.isTouchable()).thenReturn(false);
+ final int windowId = mA11yWindowManager.findWindowIdLocked(
+ USER_SYSTEM_ID, window.getWindowInfo().token);
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+ final List<AccessibilityWindowInfo> a11yWindows =
+ mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ assertThat(a11yWindows, hasItem(windowId(windowId)));
+ }
+
+ @Test
+ public void onWindowsChanged_trustedFocusedNonTouchableWindow_shouldNotHideWindowsBelow() {
+ // Make the focused trusted un-touchable window fullscreen.
+ final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
+ DEFAULT_FOCUSED_INDEX);
+ setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ when(window.isTouchable()).thenReturn(false);
+ when(window.isTrustedOverlay()).thenReturn(true);
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+ final List<AccessibilityWindowInfo> a11yWindows =
+ mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
+ }
+
+ @Test
+ public void onWindowsChanged_accessibilityOverlay_shouldNotHideWindowsBelow() {
+ // Make the a11y overlay window fullscreen.
+ final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+ setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ when(window.getType()).thenReturn(WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY);
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+ final List<AccessibilityWindowInfo> a11yWindows =
+ mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
+ }
+
+ @Test
+ public void onWindowsChanged_shouldReportFocusedWindowEvenIfOccluded() {
+ // Make the front window fullscreen.
+ final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+ setRegionForMockAccessibilityWindow(frontWindow,
+ new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
+ USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
+
+ final AccessibilityWindow focusedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(
+ DEFAULT_FOCUSED_INDEX);
+ final int focusedWindowId = mA11yWindowManager.findWindowIdLocked(
+ USER_SYSTEM_ID, focusedWindow.getWindowInfo().token);
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+ final List<AccessibilityWindowInfo> a11yWindows =
+ mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ assertThat(a11yWindows, hasSize(2));
+ assertThat(a11yWindows.get(0), windowId(frontWindowId));
+ assertThat(a11yWindows.get(1), windowId(focusedWindowId));
+ }
+
+ @Test
+ public void onWindowsChanged_embeddedWindows_shouldOnlyReportHost() throws RemoteException {
+ final Rect embeddingBounds = new Rect(0, 0, 200, 100);
+
+ // The embedded window comes front of the host window.
+ final IBinder embeddedWindowLeashToken = Mockito.mock(IBinder.class);
+ final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
+ false, embeddedWindowLeashToken, USER_SYSTEM_ID);
+ final AccessibilityWindow embeddedWindow = createMockAccessibilityWindow(
+ mA11yWindowTokens.get(embeddedWindowId), Display.DEFAULT_DISPLAY);
+ setRegionForMockAccessibilityWindow(embeddedWindow, new Region(embeddingBounds));
+ mWindows.get(Display.DEFAULT_DISPLAY).set(0, embeddedWindow);
+
+ final IBinder hostWindowLeashToken = Mockito.mock(IBinder.class);
+ final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
+ false, hostWindowLeashToken, USER_SYSTEM_ID);
+ final AccessibilityWindow hostWindow = createMockAccessibilityWindow(
+ mA11yWindowTokens.get(hostWindowId), Display.DEFAULT_DISPLAY);
+ setRegionForMockAccessibilityWindow(hostWindow, new Region(embeddingBounds));
+ mWindows.get(Display.DEFAULT_DISPLAY).set(1, hostWindow);
+
+ mA11yWindowManager.associateEmbeddedHierarchyLocked(
+ hostWindowLeashToken, embeddedWindowLeashToken);
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+ final List<AccessibilityWindowInfo> a11yWindows =
+ mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ assertThat(a11yWindows, not(hasItem(windowId(embeddedWindowId))));
+ assertThat(a11yWindows.get(0), windowId(hostWindowId));
+ final Rect bounds = new Rect();
+ a11yWindows.get(0).getBoundsInScreen(bounds);
+ assertEquals(bounds, embeddingBounds);
+ }
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
- assertNotEquals(correctLayer,
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer());
+ @Test
+ public void onWindowsChanged_shouldNotReportfullyOccludedWindow() {
+ final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+ setRegionForMockAccessibilityWindow(frontWindow, new Region(100, 100, 300, 300));
+ final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
+ USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
+
+ // index 1 is focused. Let's use the next one for this test.
+ final AccessibilityWindow occludedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(2);
+ setRegionForMockAccessibilityWindow(occludedWindow, new Region(150, 150, 250, 250));
+ final int occludedWindowId = mA11yWindowManager.findWindowIdLocked(
+ USER_SYSTEM_ID, occludedWindow.getWindowInfo().token);
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
+ final List<AccessibilityWindowInfo> a11yWindows =
+ mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ assertThat(a11yWindows, hasItem(windowId(frontWindowId)));
+ assertThat(a11yWindows, not(hasItem(windowId(occludedWindowId))));
}
@Test
- public void onWindowsChangedNoForceSend_layerChanged_shouldNotUpdateWindows() {
- final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
- final int correctLayer =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer();
- windowInfo.layer += 1;
+ public void onWindowsChangedAndForceSend_shouldUpdateWindows() {
+ assertNotEquals("new title",
+ toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
+ .get(0).getTitle()));
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
- assertEquals(correctLayer,
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0).getLayer());
+ mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().title = "new title";
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+ assertEquals("new title",
+ toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
+ .get(0).getTitle()));
}
@Test
@@ -368,14 +493,10 @@ public class AccessibilityWindowManagerTest {
mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0);
final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
true, USER_SYSTEM_ID);
- final WindowInfo windowInfo = WindowInfo.obtain();
- windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
- windowInfo.token = token.asBinder();
- windowInfo.layer = 0;
- windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
- mWindowInfos.get(Display.DEFAULT_DISPLAY).set(0, windowInfo);
+ mWindows.get(Display.DEFAULT_DISPLAY).set(0,
+ createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
assertNotEquals(oldWindow,
mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0));
}
@@ -383,12 +504,12 @@ public class AccessibilityWindowManagerTest {
@Test
public void onWindowsChangedNoForceSend_focusChanged_shouldUpdateWindows() {
final WindowInfo focusedWindowInfo =
- mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX);
- final WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
+ mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
+ final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo();
focusedWindowInfo.focused = false;
windowInfo.focused = true;
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
assertTrue(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0)
.isFocused());
}
@@ -497,15 +618,18 @@ public class AccessibilityWindowManagerTest {
@Test
public void computePartialInteractiveRegionForWindow_wholeVisible_returnWholeRegion() {
// Updates top 2 z-order WindowInfo are whole visible.
- WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
- windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
- windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(1);
- windowInfo.regionInScreen.set(0, SCREEN_HEIGHT / 2,
- SCREEN_WIDTH, SCREEN_HEIGHT);
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+ final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+ setRegionForMockAccessibilityWindow(firstWindow,
+ new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
+ final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
+ setRegionForMockAccessibilityWindow(secondWindow,
+ new Region(0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
final List<AccessibilityWindowInfo> a11yWindows =
mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ assertThat(a11yWindows, hasSize(2));
final Region outBounds = new Region();
int windowId = a11yWindows.get(0).getId();
@@ -523,12 +647,17 @@ public class AccessibilityWindowManagerTest {
@Test
public void computePartialInteractiveRegionForWindow_halfVisible_returnHalfRegion() {
// Updates z-order #1 WindowInfo is half visible.
- WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
- windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2);
-
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+ final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+ setRegionForMockAccessibilityWindow(firstWindow,
+ new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
+ final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
+ setRegionForMockAccessibilityWindow(secondWindow,
+ new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
final List<AccessibilityWindowInfo> a11yWindows =
mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ assertThat(a11yWindows, hasSize(2));
final Region outBounds = new Region();
int windowId = a11yWindows.get(1).getId();
@@ -539,9 +668,17 @@ public class AccessibilityWindowManagerTest {
@Test
public void computePartialInteractiveRegionForWindow_notVisible_returnEmptyRegion() {
- // Since z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
+ // z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
+ final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+ setRegionForMockAccessibilityWindow(firstWindow,
+ new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+
final List<AccessibilityWindowInfo> a11yWindows =
mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ // Note that the second window is also exposed even if region is empty because it's focused.
+ assertThat(a11yWindows, hasSize(2));
final Region outBounds = new Region();
int windowId = a11yWindows.get(1).getId();
@@ -552,16 +689,21 @@ public class AccessibilityWindowManagerTest {
@Test
public void computePartialInteractiveRegionForWindow_partialVisible_returnVisibleRegion() {
// Updates z-order #0 WindowInfo to have two interact-able areas.
- Region region = new Region(0, 0, SCREEN_WIDTH, 200);
+ final Region region = new Region(0, 0, SCREEN_WIDTH, 200);
region.op(0, SCREEN_HEIGHT - 200, SCREEN_WIDTH, SCREEN_HEIGHT, Region.Op.UNION);
- WindowInfo windowInfo = mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0);
- windowInfo.regionInScreen.set(region);
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+ final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
+ setRegionForMockAccessibilityWindow(firstWindow, region);
+ final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
+ setRegionForMockAccessibilityWindow(secondWindow,
+ new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
final List<AccessibilityWindowInfo> a11yWindows =
mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
+ assertThat(a11yWindows, hasSize(2));
final Region outBounds = new Region();
- int windowId = a11yWindows.get(1).getId();
+ final int windowId = a11yWindows.get(1).getId();
mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
assertFalse(outBounds.getBounds().isEmpty());
@@ -572,7 +714,8 @@ public class AccessibilityWindowManagerTest {
@Test
public void updateActiveAndA11yFocusedWindow_windowStateChangedEvent_noTracking_shouldUpdate() {
final IBinder eventWindowToken =
- mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX + 1).token;
+ mWindows.get(Display.DEFAULT_DISPLAY)
+ .get(DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().token;
final int eventWindowId = mA11yWindowManager.findWindowIdLocked(
USER_SYSTEM_ID, eventWindowToken);
when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
@@ -611,11 +754,11 @@ public class AccessibilityWindowManagerTest {
.sendAccessibilityEventForCurrentUserLocked(captor.capture());
assertThat(captor.getAllValues().get(0),
allOf(displayId(Display.DEFAULT_DISPLAY),
- a11yWindowId(currentActiveWindowId),
+ eventWindowId(currentActiveWindowId),
a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
assertThat(captor.getAllValues().get(1),
allOf(displayId(Display.DEFAULT_DISPLAY),
- a11yWindowId(eventWindowId),
+ eventWindowId(eventWindowId),
a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
}
@@ -641,7 +784,7 @@ public class AccessibilityWindowManagerTest {
.sendAccessibilityEventForCurrentUserLocked(captor.capture());
assertThat(captor.getAllValues().get(0),
allOf(displayId(Display.DEFAULT_DISPLAY),
- a11yWindowId(eventWindowId),
+ eventWindowId(eventWindowId),
a11yWindowChanges(
AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
}
@@ -690,12 +833,12 @@ public class AccessibilityWindowManagerTest {
.sendAccessibilityEventForCurrentUserLocked(captor.capture());
assertThat(captor.getAllValues().get(0),
allOf(displayId(initialDisplayId),
- a11yWindowId(initialWindowId),
+ eventWindowId(initialWindowId),
a11yWindowChanges(
AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
assertThat(captor.getAllValues().get(1),
allOf(displayId(eventDisplayId),
- a11yWindowId(eventWindowId),
+ eventWindowId(eventWindowId),
a11yWindowChanges(
AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
}
@@ -722,7 +865,7 @@ public class AccessibilityWindowManagerTest {
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED,
noUse);
assertThat(mA11yWindowManager.getFocusedWindowId(
- AccessibilityNodeInfo.FOCUS_ACCESSIBILITY),
+ AccessibilityNodeInfo.FOCUS_ACCESSIBILITY),
is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID));
}
@@ -751,11 +894,11 @@ public class AccessibilityWindowManagerTest {
.sendAccessibilityEventForCurrentUserLocked(captor.capture());
assertThat(captor.getAllValues().get(0),
allOf(displayId(Display.DEFAULT_DISPLAY),
- a11yWindowId(eventWindowId),
+ eventWindowId(eventWindowId),
a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
assertThat(captor.getAllValues().get(1),
allOf(displayId(Display.DEFAULT_DISPLAY),
- a11yWindowId(currentActiveWindowId),
+ eventWindowId(currentActiveWindowId),
a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
}
@@ -763,7 +906,8 @@ public class AccessibilityWindowManagerTest {
public void onTouchInteractionEnd_noServiceInteractiveWindow_shouldClearA11yFocus()
throws RemoteException {
final IBinder defaultFocusWinToken =
- mWindowInfos.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).token;
+ mWindows.get(Display.DEFAULT_DISPLAY).get(
+ DEFAULT_FOCUSED_INDEX).getWindowInfo().token;
final int defaultFocusWindowId = mA11yWindowManager.findWindowIdLocked(
USER_SYSTEM_ID, defaultFocusWinToken);
when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
@@ -808,8 +952,8 @@ public class AccessibilityWindowManagerTest {
@Test
public void getPictureInPictureWindow_shouldNotNull() {
assertNull(mA11yWindowManager.getPictureInPictureWindowLocked());
- mWindowInfos.get(Display.DEFAULT_DISPLAY).get(1).inPictureInPicture = true;
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+ mWindows.get(Display.DEFAULT_DISPLAY).get(1).getWindowInfo().inPictureInPicture = true;
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
assertNotNull(mA11yWindowManager.getPictureInPictureWindowLocked());
}
@@ -823,8 +967,9 @@ public class AccessibilityWindowManagerTest {
final IAccessibilityInteractionConnection mockRemoteConnection =
mA11yWindowManager.getConnectionLocked(
USER_SYSTEM_ID, outsideWindowId).getRemote();
- mWindowInfos.get(Display.DEFAULT_DISPLAY).get(0).hasFlagWatchOutsideTouch = true;
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
+ mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().hasFlagWatchOutsideTouch =
+ true;
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
mA11yWindowManager.notifyOutsideTouch(USER_SYSTEM_ID, targetWindowId);
verify(mockRemoteConnection).notifyOutsideTouch();
@@ -942,18 +1087,14 @@ public class AccessibilityWindowManagerTest {
@Test
public void sendAccessibilityEventOnWindowRemoval() {
- final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);
+ final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
// Removing index 0 because it's not focused, and avoids unnecessary layer change.
final int windowId =
getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
- infos.remove(0);
- for (WindowInfo info : infos) {
- // Adjust layer number because it should start from 0.
- info.layer--;
- }
+ windows.remove(0);
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
final ArgumentCaptor<AccessibilityEvent> captor =
ArgumentCaptor.forClass(AccessibilityEvent.class);
@@ -961,27 +1102,21 @@ public class AccessibilityWindowManagerTest {
.sendAccessibilityEventForCurrentUserLocked(captor.capture());
assertThat(captor.getAllValues().get(0),
allOf(displayId(Display.DEFAULT_DISPLAY),
- a11yWindowId(windowId),
+ eventWindowId(windowId),
a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_REMOVED)));
}
@Test
public void sendAccessibilityEventOnWindowAddition() throws RemoteException {
- final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);
-
- for (WindowInfo info : infos) {
- // Adjust layer number because new window will have 0 so that layer number in
- // A11yWindowInfo in window won't be changed.
- info.layer++;
- }
+ final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
false, USER_SYSTEM_ID);
- addWindowInfo(infos, token, 0);
- final int windowId =
- getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, infos.size() - 1);
+ // Adding window to the front so that other windows' layer won't change.
+ windows.add(0, createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
+ final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
final ArgumentCaptor<AccessibilityEvent> captor =
ArgumentCaptor.forClass(AccessibilityEvent.class);
@@ -989,17 +1124,17 @@ public class AccessibilityWindowManagerTest {
.sendAccessibilityEventForCurrentUserLocked(captor.capture());
assertThat(captor.getAllValues().get(0),
allOf(displayId(Display.DEFAULT_DISPLAY),
- a11yWindowId(windowId),
+ eventWindowId(windowId),
a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ADDED)));
}
@Test
public void sendAccessibilityEventOnWindowChange() {
- final ArrayList<WindowInfo> infos = mWindowInfos.get(Display.DEFAULT_DISPLAY);
- infos.get(0).title = "new title";
+ final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
+ windows.get(0).getWindowInfo().title = "new title";
final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
- onWindowsForAccessibilityChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
+ onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
final ArgumentCaptor<AccessibilityEvent> captor =
ArgumentCaptor.forClass(AccessibilityEvent.class);
@@ -1007,7 +1142,7 @@ public class AccessibilityWindowManagerTest {
.sendAccessibilityEventForCurrentUserLocked(captor.capture());
assertThat(captor.getAllValues().get(0),
allOf(displayId(Display.DEFAULT_DISPLAY),
- a11yWindowId(windowId),
+ eventWindowId(windowId),
a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_TITLE)));
}
@@ -1017,48 +1152,47 @@ public class AccessibilityWindowManagerTest {
}
private void startTrackingPerDisplay(int displayId) throws RemoteException {
- ArrayList<WindowInfo> windowInfosForDisplay = new ArrayList<>();
+ ArrayList<AccessibilityWindow> windowsForDisplay = new ArrayList<>();
// Adds RemoteAccessibilityConnection into AccessibilityWindowManager, and copy
// mock window token into mA11yWindowTokens. Also, preparing WindowInfo mWindowInfos
// for the test.
- int layer = 0;
for (int i = 0; i < NUM_GLOBAL_WINDOWS; i++) {
final IWindow token = addAccessibilityInteractionConnection(displayId,
true, USER_SYSTEM_ID);
- addWindowInfo(windowInfosForDisplay, token, layer++);
+ windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
}
for (int i = 0; i < NUM_APP_WINDOWS; i++) {
final IWindow token = addAccessibilityInteractionConnection(displayId,
false, USER_SYSTEM_ID);
- addWindowInfo(windowInfosForDisplay, token, layer++);
+ windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
}
// Sets up current focused window of display.
// Each display has its own current focused window if config_perDisplayFocusEnabled is true.
// Otherwise only default display needs to current focused window.
if (mSupportPerDisplayFocus || displayId == Display.DEFAULT_DISPLAY) {
- windowInfosForDisplay.get(DEFAULT_FOCUSED_INDEX).focused = true;
+ windowsForDisplay.get(DEFAULT_FOCUSED_INDEX).getWindowInfo().focused = true;
}
// Turns on windows tracking, and update window info.
mA11yWindowManager.startTrackingWindows(displayId, false);
// Puts window lists into array.
- mWindowInfos.put(displayId, windowInfosForDisplay);
+ mWindows.put(displayId, windowsForDisplay);
// Sets the default display is the top focused display and
// its current focused window is the top focused window.
if (displayId == Display.DEFAULT_DISPLAY) {
setTopFocusedWindowAndDisplay(displayId, DEFAULT_FOCUSED_INDEX);
}
// Invokes callback for sending window lists to A11y framework.
- onWindowsForAccessibilityChanged(displayId, FORCE_SEND);
+ onAccessibilityWindowsChanged(displayId, FORCE_SEND);
assertEquals(mA11yWindowManager.getWindowListLocked(displayId).size(),
- windowInfosForDisplay.size());
+ windowsForDisplay.size());
}
private WindowsForAccessibilityCallback getWindowsForAccessibilityCallbacks(int displayId) {
ArgumentCaptor<WindowsForAccessibilityCallback> windowsForAccessibilityCallbacksCaptor =
ArgumentCaptor.forClass(
- WindowManagerInternal.WindowsForAccessibilityCallback.class);
+ WindowsForAccessibilityCallback.class);
verify(mMockWindowManagerInternal)
.setWindowsForAccessibilityCallback(eq(displayId),
windowsForAccessibilityCallbacksCaptor.capture());
@@ -1106,36 +1240,28 @@ public class AccessibilityWindowManagerTest {
return windowId;
}
- private void addWindowInfo(ArrayList<WindowInfo> windowInfos, IWindow windowToken, int layer) {
- final WindowInfo windowInfo = WindowInfo.obtain();
- windowInfo.type = AccessibilityWindowInfo.TYPE_APPLICATION;
- windowInfo.token = windowToken.asBinder();
- windowInfo.layer = layer;
- windowInfo.regionInScreen.set(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
- windowInfos.add(windowInfo);
- }
-
private int getWindowIdFromWindowInfosForDisplay(int displayId, int index) {
- final IBinder windowToken = mWindowInfos.get(displayId).get(index).token;
+ final IBinder windowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
return mA11yWindowManager.findWindowIdLocked(
USER_SYSTEM_ID, windowToken);
}
private void setTopFocusedWindowAndDisplay(int displayId, int index) {
// Sets the top focus window.
- mTopFocusedWindowToken = mWindowInfos.get(displayId).get(index).token;
+ mTopFocusedWindowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
// Sets the top focused display.
mTopFocusedDisplayId = displayId;
}
- private void onWindowsForAccessibilityChanged(int displayId, boolean forceSend) {
+ private void onAccessibilityWindowsChanged(int displayId, boolean forceSend) {
WindowsForAccessibilityCallback callbacks = mCallbackOfWindows.get(displayId);
if (callbacks == null) {
callbacks = getWindowsForAccessibilityCallbacks(displayId);
mCallbackOfWindows.put(displayId, callbacks);
}
- callbacks.onWindowsForAccessibilityChanged(forceSend, mTopFocusedDisplayId,
- mTopFocusedWindowToken, mWindowInfos.get(displayId));
+ callbacks.onAccessibilityWindowsChanged(forceSend, mTopFocusedDisplayId,
+ mTopFocusedWindowToken, new Point(SCREEN_WIDTH, SCREEN_HEIGHT),
+ mWindows.get(displayId));
}
private void changeFocusedWindowOnDisplayPerDisplayFocusConfig(
@@ -1144,23 +1270,23 @@ public class AccessibilityWindowManagerTest {
if (mSupportPerDisplayFocus) {
// Gets the old focused window of display which wants to change focused window.
WindowInfo focusedWindowInfo =
- mWindowInfos.get(changeFocusedDisplayId).get(oldFocusedWindowIndex);
+ mWindows.get(changeFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
// Resets the focus of old focused window.
focusedWindowInfo.focused = false;
// Gets the new window of display which wants to change focused window.
focusedWindowInfo =
- mWindowInfos.get(changeFocusedDisplayId).get(newFocusedWindowIndex);
+ mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
// Sets the focus of new focused window.
focusedWindowInfo.focused = true;
} else {
// Gets the window of display which wants to change focused window.
WindowInfo focusedWindowInfo =
- mWindowInfos.get(changeFocusedDisplayId).get(newFocusedWindowIndex);
+ mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
// Sets the focus of new focused window.
focusedWindowInfo.focused = true;
// Gets the old focused window of old top focused display.
focusedWindowInfo =
- mWindowInfos.get(oldTopFocusedDisplayId).get(oldFocusedWindowIndex);
+ mWindows.get(oldTopFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
// Resets the focus of old focused window.
focusedWindowInfo.focused = false;
// Changes the top focused display and window.
@@ -1168,6 +1294,39 @@ public class AccessibilityWindowManagerTest {
}
}
+ private AccessibilityWindow createMockAccessibilityWindow(IWindow windowToken, int displayId) {
+ final WindowInfo windowInfo = WindowInfo.obtain();
+ windowInfo.type = WindowManager.LayoutParams.TYPE_APPLICATION;
+ windowInfo.token = windowToken.asBinder();
+
+ final AccessibilityWindow window = Mockito.mock(AccessibilityWindow.class);
+ when(window.getWindowInfo()).thenReturn(windowInfo);
+ when(window.isFocused()).thenAnswer(invocation -> windowInfo.focused);
+ when(window.isTouchable()).thenReturn(true);
+ when(window.getType()).thenReturn(windowInfo.type);
+
+ setRegionForMockAccessibilityWindow(window, nextToucableRegion(displayId));
+ return window;
+ }
+
+ private void setRegionForMockAccessibilityWindow(AccessibilityWindow window, Region region) {
+ doAnswer(invocation -> {
+ ((Region) invocation.getArgument(0)).set(region);
+ return null;
+ }).when(window).getTouchableRegionInScreen(any(Region.class));
+ doAnswer(invocation -> {
+ ((Region) invocation.getArgument(0)).set(region);
+ return null;
+ }).when(window).getTouchableRegionInWindow(any(Region.class));
+ }
+
+ private Region nextToucableRegion(int displayId) {
+ final int topLeft = mNextRegionOffsets.get(displayId, 0);
+ final int bottomRight = topLeft + 100;
+ mNextRegionOffsets.put(displayId, topLeft + 10);
+ return new Region(topLeft, topLeft, bottomRight, bottomRight);
+ }
+
@Nullable
private static String toString(@Nullable CharSequence cs) {
return cs == null ? null : cs.toString();
@@ -1196,16 +1355,16 @@ public class AccessibilityWindowManagerTest {
}
}
- static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
+ static class EventWindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
private int mWindowId;
- WindowIdMatcher(int windowId) {
+ EventWindowIdMatcher(int windowId) {
super();
mWindowId = windowId;
}
- static WindowIdMatcher a11yWindowId(int windowId) {
- return new WindowIdMatcher(windowId);
+ static EventWindowIdMatcher eventWindowId(int windowId) {
+ return new EventWindowIdMatcher(windowId);
}
@Override
@@ -1241,5 +1400,27 @@ public class AccessibilityWindowManagerTest {
description.appendText("Matching to window changes " + mWindowChanges);
}
}
+
+ static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityWindowInfo> {
+ private final int mWindowId;
+
+ WindowIdMatcher(int windowId) {
+ super();
+ mWindowId = windowId;
+ }
+
+ static WindowIdMatcher windowId(int windowId) {
+ return new WindowIdMatcher(windowId);
+ }
+
+ @Override
+ protected boolean matchesSafely(AccessibilityWindowInfo window) {
+ return window.getId() == mWindowId;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Matching to windowId " + mWindowId);
+ }
+ }
}
-// LINT.ThenChange(/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java)
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java
deleted file mode 100644
index 19041451c8eb..000000000000
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerWithAccessibilityWindowTest.java
+++ /dev/null
@@ -1,1444 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.accessibility;
-
-import static com.android.server.accessibility.AbstractAccessibilityServiceConnection.DISPLAY_TYPE_DEFAULT;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.DisplayIdMatcher.displayId;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.WindowIdMatcher.windowId;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.WindowChangesMatcher.a11yWindowChanges;
-import static com.android.server.accessibility.AccessibilityWindowManagerWithAccessibilityWindowTest.EventWindowIdMatcher.eventWindowId;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.allOf;
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.Nullable;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.os.IBinder;
-import android.os.LocaleList;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-import android.util.SparseArray;
-import android.view.Display;
-import android.view.IWindow;
-import android.view.WindowInfo;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityWindowAttributes;
-import android.view.accessibility.AccessibilityWindowInfo;
-import android.view.accessibility.IAccessibilityInteractionConnection;
-
-import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
-import com.android.server.accessibility.test.MessageCapturingHandler;
-import com.android.server.wm.AccessibilityWindowsPopulator.AccessibilityWindow;
-import com.android.server.wm.WindowManagerInternal;
-import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback;
-
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Tests for the AccessibilityWindowManager with Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2
- * TODO(b/322444245): Merge with AccessibilityWindowManagerTest
- * after completing the flag migration.
- */
-@RequiresFlagsEnabled(Flags.FLAG_COMPUTE_WINDOW_CHANGES_ON_A11Y_V2)
-public class AccessibilityWindowManagerWithAccessibilityWindowTest {
- private static final String PACKAGE_NAME = "com.android.server.accessibility";
- private static final boolean FORCE_SEND = true;
- private static final boolean SEND_ON_WINDOW_CHANGES = false;
- private static final int USER_SYSTEM_ID = UserHandle.USER_SYSTEM;
- private static final int USER_PROFILE = 11;
- private static final int USER_PROFILE_PARENT = 1;
- private static final int SECONDARY_DISPLAY_ID = Display.DEFAULT_DISPLAY + 1;
- private static final int NUM_GLOBAL_WINDOWS = 4;
- private static final int NUM_APP_WINDOWS = 4;
- private static final int NUM_OF_WINDOWS = (NUM_GLOBAL_WINDOWS + NUM_APP_WINDOWS);
- private static final int DEFAULT_FOCUSED_INDEX = 1;
- private static final int SCREEN_WIDTH = 1080;
- private static final int SCREEN_HEIGHT = 1920;
- private static final int INVALID_ID = AccessibilityWindowInfo.UNDEFINED_WINDOW_ID;
- private static final int HOST_WINDOW_ID = 10;
- private static final int EMBEDDED_WINDOW_ID = 11;
- private static final int OTHER_WINDOW_ID = 12;
-
- private AccessibilityWindowManager mA11yWindowManager;
- // Window manager will support multiple focused window if config_perDisplayFocusEnabled is true,
- // i.e., each display would have its current focused window, and one of all focused windows
- // would be top focused window. Otherwise, window manager only supports one focused window
- // at all displays, and that focused window would be top focused window.
- private boolean mSupportPerDisplayFocus = false;
- private int mTopFocusedDisplayId = Display.INVALID_DISPLAY;
- private IBinder mTopFocusedWindowToken = null;
-
- // List of window token, mapping from windowId -> window token.
- private final SparseArray<IWindow> mA11yWindowTokens = new SparseArray<>();
- // List of window info lists, mapping from displayId -> a11y window lists.
- private final SparseArray<ArrayList<AccessibilityWindow>> mWindows = new SparseArray<>();
- // List of callback, mapping from displayId -> callback.
- private final SparseArray<WindowsForAccessibilityCallback> mCallbackOfWindows =
- new SparseArray<>();
- // List of display ID.
- private final ArrayList<Integer> mExpectedDisplayList = new ArrayList<>(Arrays.asList(
- Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID));
-
- private final MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
-
- // This maps displayId -> next region offset.
- // Touchable region must have un-occluded area so that it's exposed to a11y services.
- // This offset can be used as left and top of new region so that top-left of each region are
- // kept visible.
- // It's expected to be incremented by some amount everytime the value is used.
- private final SparseArray<Integer> mNextRegionOffsets = new SparseArray<>();
-
- @Mock
- private WindowManagerInternal mMockWindowManagerInternal;
- @Mock
- private AccessibilityWindowManager.AccessibilityEventSender mMockA11yEventSender;
- @Mock
- private AccessibilitySecurityPolicy mMockA11ySecurityPolicy;
- @Mock
- private AccessibilitySecurityPolicy.AccessibilityUserManager mMockA11yUserManager;
- @Mock
- private AccessibilityTraceManager mMockA11yTraceManager;
-
- @Mock
- private IBinder mMockHostToken;
- @Mock
- private IBinder mMockEmbeddedToken;
- @Mock
- private IBinder mMockInvalidToken;
-
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
- @Before
- public void setUp() throws RemoteException {
- MockitoAnnotations.initMocks(this);
- when(mMockA11yUserManager.getCurrentUserIdLocked()).thenReturn(USER_SYSTEM_ID);
- when(mMockA11ySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
- USER_PROFILE)).thenReturn(USER_PROFILE_PARENT);
- when(mMockA11ySecurityPolicy.resolveCallingUserIdEnforcingPermissionsLocked(
- USER_SYSTEM_ID)).thenReturn(USER_SYSTEM_ID);
- when(mMockA11ySecurityPolicy.resolveValidReportedPackageLocked(
- anyString(), anyInt(), anyInt(), anyInt())).thenReturn(PACKAGE_NAME);
-
- doAnswer((invocation) -> {
- onAccessibilityWindowsChanged(invocation.getArgument(0), false);
- return null;
- }).when(mMockWindowManagerInternal).computeWindowsForAccessibility(anyInt());
-
- mA11yWindowManager = new AccessibilityWindowManager(new Object(), mHandler,
- mMockWindowManagerInternal,
- mMockA11yEventSender,
- mMockA11ySecurityPolicy,
- mMockA11yUserManager,
- mMockA11yTraceManager);
- // Starts tracking window of default display and sets the default display
- // as top focused display before each testing starts.
- startTrackingPerDisplay(Display.DEFAULT_DISPLAY);
-
- // AccessibilityEventSender is invoked during onAccessibilityWindowsChanged.
- // Resets it for mockito verify of further test case.
- Mockito.reset(mMockA11yEventSender);
-
- registerLeashedTokenAndWindowId();
- }
-
- @After
- public void tearDown() {
- mHandler.removeAllMessages();
- }
-
- @Test
- public void startTrackingWindows_shouldEnableWindowManagerCallback() {
- // AccessibilityWindowManager#startTrackingWindows already invoked in setup.
- assertTrue(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
- final WindowsForAccessibilityCallback callbacks =
- mCallbackOfWindows.get(Display.DEFAULT_DISPLAY);
- verify(mMockWindowManagerInternal).setWindowsForAccessibilityCallback(
- eq(Display.DEFAULT_DISPLAY), eq(callbacks));
- }
-
- @Test
- public void stopTrackingWindows_shouldDisableWindowManagerCallback() {
- assertTrue(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
- Mockito.reset(mMockWindowManagerInternal);
-
- mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
- assertFalse(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
- verify(mMockWindowManagerInternal).setWindowsForAccessibilityCallback(
- eq(Display.DEFAULT_DISPLAY), isNull());
-
- }
-
- @Test
- public void stopTrackingWindows_shouldClearWindows() {
- assertTrue(mA11yWindowManager.isTrackingWindowsLocked(Display.DEFAULT_DISPLAY));
- final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
-
- mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
- assertNull(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY));
- assertEquals(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
- AccessibilityWindowInfo.UNDEFINED_WINDOW_ID);
- assertEquals(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID),
- activeWindowId);
- }
-
- @Test
- public void stopTrackingWindows_onNonTopFocusedDisplay_shouldNotResetTopFocusWindow()
- throws RemoteException {
- // At setup, the default display sets be the top focused display and
- // its current focused window sets be the top focused window.
- // Starts tracking window of second display.
- startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
- assertTrue(mA11yWindowManager.isTrackingWindowsLocked(SECONDARY_DISPLAY_ID));
- // Stops tracking windows of second display.
- mA11yWindowManager.stopTrackingWindows(SECONDARY_DISPLAY_ID);
- assertNotEquals(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
- AccessibilityWindowInfo.UNDEFINED_WINDOW_ID);
- }
-
- @Test
- public void onWindowsChanged_duringTouchInteractAndFocusChange_shouldChangeActiveWindow() {
- final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
- final WindowInfo focusedWindowInfo =
- mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
- assertEquals(activeWindowId, mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, focusedWindowInfo.token));
-
- focusedWindowInfo.focused = false;
- mWindows.get(Display.DEFAULT_DISPLAY).get(
- DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().focused = true;
-
- mA11yWindowManager.onTouchInteractionStart();
- setTopFocusedWindowAndDisplay(Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX + 1);
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
- }
-
- @Test
- public void
- onWindowsChanged_focusChangeOnNonTopFocusedDisplay_perDisplayFocusOn_notChangeWindow()
- throws RemoteException {
- // At setup, the default display sets be the top focused display and
- // its current focused window sets be the top focused window.
- // Sets supporting multiple focused window, i.e., config_perDisplayFocusEnabled is true.
- mSupportPerDisplayFocus = true;
- // Starts tracking window of second display.
- startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
- // Gets the active window.
- final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
- // Gets the top focused window.
- final int topFocusedWindowId =
- mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT);
- // Changes the current focused window at second display.
- changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
- DEFAULT_FOCUSED_INDEX + 1, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
-
- onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
- // The active window should not be changed.
- assertEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
- // The top focused window should not be changed.
- assertEquals(topFocusedWindowId,
- mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT));
- }
-
- @Test
- public void
- onWindowChange_focusChangeToNonTopFocusedDisplay_perDisplayFocusOff_shouldChangeWindow()
- throws RemoteException {
- // At setup, the default display sets be the top focused display and
- // its current focused window sets be the top focused window.
- // Sets not supporting multiple focused window, i.e., config_perDisplayFocusEnabled is
- // false.
- mSupportPerDisplayFocus = false;
- // Starts tracking window of second display.
- startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
- // Gets the active window.
- final int activeWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
- // Gets the top focused window.
- final int topFocusedWindowId =
- mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT);
- // Changes the current focused window from default display to second display.
- changeFocusedWindowOnDisplayPerDisplayFocusConfig(SECONDARY_DISPLAY_ID,
- DEFAULT_FOCUSED_INDEX, Display.DEFAULT_DISPLAY, DEFAULT_FOCUSED_INDEX);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
- onAccessibilityWindowsChanged(SECONDARY_DISPLAY_ID, SEND_ON_WINDOW_CHANGES);
- // The active window should be changed.
- assertNotEquals(activeWindowId, mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID));
- // The top focused window should be changed.
- assertNotEquals(topFocusedWindowId,
- mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT));
- }
-
- @Test
- public void onWindowsChanged_shouldReportCorrectLayer() {
- // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
- List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- for (int i = 0; i < a11yWindows.size(); i++) {
- final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
- assertThat(mWindows.get(Display.DEFAULT_DISPLAY).size() - i - 1,
- is(a11yWindow.getLayer()));
- }
- }
-
- @Test
- public void onWindowsChanged_shouldReportCorrectOrder() {
- // AccessibilityWindowManager#onAccessibilityWindowsChanged already invoked in setup.
- List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- for (int i = 0; i < a11yWindows.size(); i++) {
- final AccessibilityWindowInfo a11yWindow = a11yWindows.get(i);
- final IBinder windowToken = mA11yWindowManager
- .getWindowTokenForUserAndWindowIdLocked(USER_SYSTEM_ID, a11yWindow.getId());
- final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY)
- .get(i).getWindowInfo();
- assertThat(windowToken, is(windowInfo.token));
- }
- }
-
- @Test
- public void onWindowsChanged_shouldNotReportNonTouchableWindow() {
- final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
- when(window.isTouchable()).thenReturn(false);
- final int windowId = mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, window.getWindowInfo().token);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- assertThat(a11yWindows, not(hasItem(windowId(windowId))));
- }
-
- @Test
- public void onWindowsChanged_shouldReportFocusedNonTouchableWindow() {
- final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
- DEFAULT_FOCUSED_INDEX);
- when(window.isTouchable()).thenReturn(false);
- final int windowId = mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, window.getWindowInfo().token);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- assertThat(a11yWindows, hasItem(windowId(windowId)));
- }
-
- @Test
- public void onWindowsChanged_trustedFocusedNonTouchableWindow_shouldNotHideWindowsBelow() {
- // Make the focused trusted un-touchable window fullscreen.
- final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(
- DEFAULT_FOCUSED_INDEX);
- setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
- when(window.isTouchable()).thenReturn(false);
- when(window.isTrustedOverlay()).thenReturn(true);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
- }
-
- @Test
- public void onWindowsChanged_accessibilityOverlay_shouldNotHideWindowsBelow() {
- // Make the a11y overlay window fullscreen.
- final AccessibilityWindow window = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
- setRegionForMockAccessibilityWindow(window, new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
- when(window.getType()).thenReturn(WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- assertThat(a11yWindows, hasSize(NUM_OF_WINDOWS));
- }
-
- @Test
- public void onWindowsChanged_shouldReportFocusedWindowEvenIfOccluded() {
- // Make the front window fullscreen.
- final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
- setRegionForMockAccessibilityWindow(frontWindow,
- new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
- final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
-
- final AccessibilityWindow focusedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(
- DEFAULT_FOCUSED_INDEX);
- final int focusedWindowId = mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, focusedWindow.getWindowInfo().token);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- assertThat(a11yWindows, hasSize(2));
- assertThat(a11yWindows.get(0), windowId(frontWindowId));
- assertThat(a11yWindows.get(1), windowId(focusedWindowId));
- }
-
- @Test
- public void onWindowsChanged_embeddedWindows_shouldOnlyReportHost() throws RemoteException {
- final Rect embeddingBounds = new Rect(0, 0, 200, 100);
-
- // The embedded window comes front of the host window.
- final IBinder embeddedWindowLeashToken = Mockito.mock(IBinder.class);
- final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
- false, embeddedWindowLeashToken, USER_SYSTEM_ID);
- final AccessibilityWindow embeddedWindow = createMockAccessibilityWindow(
- mA11yWindowTokens.get(embeddedWindowId), Display.DEFAULT_DISPLAY);
- setRegionForMockAccessibilityWindow(embeddedWindow, new Region(embeddingBounds));
- mWindows.get(Display.DEFAULT_DISPLAY).set(0, embeddedWindow);
-
- final IBinder hostWindowLeashToken = Mockito.mock(IBinder.class);
- final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
- false, hostWindowLeashToken, USER_SYSTEM_ID);
- final AccessibilityWindow hostWindow = createMockAccessibilityWindow(
- mA11yWindowTokens.get(hostWindowId), Display.DEFAULT_DISPLAY);
- setRegionForMockAccessibilityWindow(hostWindow, new Region(embeddingBounds));
- mWindows.get(Display.DEFAULT_DISPLAY).set(1, hostWindow);
-
- mA11yWindowManager.associateEmbeddedHierarchyLocked(
- hostWindowLeashToken, embeddedWindowLeashToken);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- assertThat(a11yWindows, not(hasItem(windowId(embeddedWindowId))));
- assertThat(a11yWindows.get(0), windowId(hostWindowId));
- final Rect bounds = new Rect();
- a11yWindows.get(0).getBoundsInScreen(bounds);
- assertEquals(bounds, embeddingBounds);
- }
-
- @Test
- public void onWindowsChanged_shouldNotReportfullyOccludedWindow() {
- final AccessibilityWindow frontWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
- setRegionForMockAccessibilityWindow(frontWindow, new Region(100, 100, 300, 300));
- final int frontWindowId = mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, frontWindow.getWindowInfo().token);
-
- // index 1 is focused. Let's use the next one for this test.
- final AccessibilityWindow occludedWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(2);
- setRegionForMockAccessibilityWindow(occludedWindow, new Region(150, 150, 250, 250));
- final int occludedWindowId = mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, occludedWindow.getWindowInfo().token);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- assertThat(a11yWindows, hasItem(windowId(frontWindowId)));
- assertThat(a11yWindows, not(hasItem(windowId(occludedWindowId))));
- }
-
- @Test
- public void onWindowsChangedAndForceSend_shouldUpdateWindows() {
- assertNotEquals("new title",
- toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
- .get(0).getTitle()));
-
- mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().title = "new title";
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
- assertEquals("new title",
- toString(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY)
- .get(0).getTitle()));
- }
-
- @Test
- public void onWindowsChangedNoForceSend_windowChanged_shouldUpdateWindows()
- throws RemoteException {
- final AccessibilityWindowInfo oldWindow =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0);
- final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
- true, USER_SYSTEM_ID);
- mWindows.get(Display.DEFAULT_DISPLAY).set(0,
- createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
- assertNotEquals(oldWindow,
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0));
- }
-
- @Test
- public void onWindowsChangedNoForceSend_focusChanged_shouldUpdateWindows() {
- final WindowInfo focusedWindowInfo =
- mWindows.get(Display.DEFAULT_DISPLAY).get(DEFAULT_FOCUSED_INDEX).getWindowInfo();
- final WindowInfo windowInfo = mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo();
- focusedWindowInfo.focused = false;
- windowInfo.focused = true;
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
- assertTrue(mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY).get(0)
- .isFocused());
- }
-
- @Test
- public void removeAccessibilityInteractionConnection_byWindowToken_shouldRemoved() {
- for (int i = 0; i < NUM_OF_WINDOWS; i++) {
- final int windowId = mA11yWindowTokens.keyAt(i);
- final IWindow windowToken = mA11yWindowTokens.valueAt(i);
- assertNotNull(mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId));
-
- mA11yWindowManager.removeAccessibilityInteractionConnection(windowToken);
- assertNull(mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId));
- }
- }
-
- @Test
- public void remoteAccessibilityConnection_binderDied_shouldRemoveConnection() {
- for (int i = 0; i < NUM_OF_WINDOWS; i++) {
- final int windowId = mA11yWindowTokens.keyAt(i);
- final RemoteAccessibilityConnection remoteA11yConnection =
- mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId);
- assertNotNull(remoteA11yConnection);
-
- remoteA11yConnection.binderDied();
- assertNull(mA11yWindowManager.getConnectionLocked(USER_SYSTEM_ID, windowId));
- }
- }
-
- @Test
- public void getWindowTokenForUserAndWindowId_shouldNotNull() {
- final List<AccessibilityWindowInfo> windows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- for (int i = 0; i < windows.size(); i++) {
- final int windowId = windows.get(i).getId();
-
- assertNotNull(mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(
- USER_SYSTEM_ID, windowId));
- }
- }
-
- @Test
- public void findWindowId() {
- final List<AccessibilityWindowInfo> windows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- for (int i = 0; i < windows.size(); i++) {
- final int windowId = windows.get(i).getId();
- final IBinder windowToken = mA11yWindowManager.getWindowTokenForUserAndWindowIdLocked(
- USER_SYSTEM_ID, windowId);
-
- assertEquals(mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, windowToken), windowId);
- }
- }
-
- @Test
- public void resolveParentWindowId_windowIsNotEmbedded_shouldReturnGivenId()
- throws RemoteException {
- final int windowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY, false,
- Mockito.mock(IBinder.class), USER_SYSTEM_ID);
- assertEquals(windowId, mA11yWindowManager.resolveParentWindowIdLocked(windowId));
- }
-
- @Test
- public void resolveParentWindowId_windowIsNotRegistered_shouldReturnGivenId() {
- final int windowId = -1;
- assertEquals(windowId, mA11yWindowManager.resolveParentWindowIdLocked(windowId));
- }
-
- @Test
- public void resolveParentWindowId_windowIsAssociated_shouldReturnParentWindowId()
- throws RemoteException {
- final IBinder mockHostToken = Mockito.mock(IBinder.class);
- final IBinder mockEmbeddedToken = Mockito.mock(IBinder.class);
- final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
- false, mockHostToken, USER_SYSTEM_ID);
- final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
- false, mockEmbeddedToken, USER_SYSTEM_ID);
-
- mA11yWindowManager.associateEmbeddedHierarchyLocked(mockHostToken, mockEmbeddedToken);
-
- final int resolvedWindowId = mA11yWindowManager.resolveParentWindowIdLocked(
- embeddedWindowId);
- assertEquals(hostWindowId, resolvedWindowId);
- }
-
- @Test
- public void resolveParentWindowId_windowIsDisassociated_shouldReturnGivenId()
- throws RemoteException {
- final IBinder mockHostToken = Mockito.mock(IBinder.class);
- final IBinder mockEmbeddedToken = Mockito.mock(IBinder.class);
- final int hostWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
- false, mockHostToken, USER_SYSTEM_ID);
- final int embeddedWindowId = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
- false, mockEmbeddedToken, USER_SYSTEM_ID);
-
- mA11yWindowManager.associateEmbeddedHierarchyLocked(mockHostToken, mockEmbeddedToken);
- mA11yWindowManager.disassociateEmbeddedHierarchyLocked(mockEmbeddedToken);
-
- final int resolvedWindowId = mA11yWindowManager.resolveParentWindowIdLocked(
- embeddedWindowId);
- assertNotEquals(hostWindowId, resolvedWindowId);
- assertEquals(embeddedWindowId, resolvedWindowId);
- }
-
- @Test
- public void computePartialInteractiveRegionForWindow_wholeVisible_returnWholeRegion() {
- // Updates top 2 z-order WindowInfo are whole visible.
- final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
- setRegionForMockAccessibilityWindow(firstWindow,
- new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
- final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
- setRegionForMockAccessibilityWindow(secondWindow,
- new Region(0, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT));
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- assertThat(a11yWindows, hasSize(2));
- final Region outBounds = new Region();
- int windowId = a11yWindows.get(0).getId();
-
- mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
- assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
- assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
-
- windowId = a11yWindows.get(1).getId();
-
- mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
- assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
- assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
- }
-
- @Test
- public void computePartialInteractiveRegionForWindow_halfVisible_returnHalfRegion() {
- // Updates z-order #1 WindowInfo is half visible.
- final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
- setRegionForMockAccessibilityWindow(firstWindow,
- new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT / 2));
- final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
- setRegionForMockAccessibilityWindow(secondWindow,
- new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- assertThat(a11yWindows, hasSize(2));
- final Region outBounds = new Region();
- int windowId = a11yWindows.get(1).getId();
-
- mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
- assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
- assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT / 2));
- }
-
- @Test
- public void computePartialInteractiveRegionForWindow_notVisible_returnEmptyRegion() {
- // z-order #0 WindowInfo is full screen, z-order #1 WindowInfo should be invisible.
- final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
- setRegionForMockAccessibilityWindow(firstWindow,
- new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- // Note that the second window is also exposed even if region is empty because it's focused.
- assertThat(a11yWindows, hasSize(2));
- final Region outBounds = new Region();
- int windowId = a11yWindows.get(1).getId();
-
- mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
- assertTrue(outBounds.getBounds().isEmpty());
- }
-
- @Test
- public void computePartialInteractiveRegionForWindow_partialVisible_returnVisibleRegion() {
- // Updates z-order #0 WindowInfo to have two interact-able areas.
- final Region region = new Region(0, 0, SCREEN_WIDTH, 200);
- region.op(0, SCREEN_HEIGHT - 200, SCREEN_WIDTH, SCREEN_HEIGHT, Region.Op.UNION);
- final AccessibilityWindow firstWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(0);
- setRegionForMockAccessibilityWindow(firstWindow, region);
- final AccessibilityWindow secondWindow = mWindows.get(Display.DEFAULT_DISPLAY).get(1);
- setRegionForMockAccessibilityWindow(secondWindow,
- new Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- final List<AccessibilityWindowInfo> a11yWindows =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- assertThat(a11yWindows, hasSize(2));
- final Region outBounds = new Region();
- final int windowId = a11yWindows.get(1).getId();
-
- mA11yWindowManager.computePartialInteractiveRegionForWindowLocked(windowId, outBounds);
- assertFalse(outBounds.getBounds().isEmpty());
- assertThat(outBounds.getBounds().width(), is(SCREEN_WIDTH));
- assertThat(outBounds.getBounds().height(), is(SCREEN_HEIGHT - 400));
- }
-
- @Test
- public void updateActiveAndA11yFocusedWindow_windowStateChangedEvent_noTracking_shouldUpdate() {
- final IBinder eventWindowToken =
- mWindows.get(Display.DEFAULT_DISPLAY)
- .get(DEFAULT_FOCUSED_INDEX + 1).getWindowInfo().token;
- final int eventWindowId = mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, eventWindowToken);
- when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
- .thenReturn(eventWindowToken);
-
- final int noUse = 0;
- mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- eventWindowId,
- noUse,
- AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
- noUse);
- assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(eventWindowId));
- assertThat(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
- is(eventWindowId));
- }
-
- @Test
- public void updateActiveAndA11yFocusedWindow_hoverEvent_touchInteract_shouldSetActiveWindow() {
- final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
- DEFAULT_FOCUSED_INDEX + 1);
- final int currentActiveWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
- assertThat(currentActiveWindowId, is(not(eventWindowId)));
-
- final int noUse = 0;
- mA11yWindowManager.onTouchInteractionStart();
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- eventWindowId,
- noUse,
- AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
- noUse);
- assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(eventWindowId));
- final ArgumentCaptor<AccessibilityEvent> captor =
- ArgumentCaptor.forClass(AccessibilityEvent.class);
- verify(mMockA11yEventSender, times(2))
- .sendAccessibilityEventForCurrentUserLocked(captor.capture());
- assertThat(captor.getAllValues().get(0),
- allOf(displayId(Display.DEFAULT_DISPLAY),
- eventWindowId(currentActiveWindowId),
- a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
- assertThat(captor.getAllValues().get(1),
- allOf(displayId(Display.DEFAULT_DISPLAY),
- eventWindowId(eventWindowId),
- a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
- }
-
- @Test
- public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_shouldUpdateA11yFocus() {
- final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
- DEFAULT_FOCUSED_INDEX);
- final int currentA11yFocusedWindowId = mA11yWindowManager.getFocusedWindowId(
- AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
- assertThat(currentA11yFocusedWindowId, is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID));
-
- final int noUse = 0;
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- eventWindowId,
- AccessibilityNodeInfo.ROOT_NODE_ID,
- AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
- noUse);
- assertThat(mA11yWindowManager.getFocusedWindowId(
- AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId));
- final ArgumentCaptor<AccessibilityEvent> captor =
- ArgumentCaptor.forClass(AccessibilityEvent.class);
- verify(mMockA11yEventSender, times(1))
- .sendAccessibilityEventForCurrentUserLocked(captor.capture());
- assertThat(captor.getAllValues().get(0),
- allOf(displayId(Display.DEFAULT_DISPLAY),
- eventWindowId(eventWindowId),
- a11yWindowChanges(
- AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
- }
-
- @Test
- public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_defaultToSecondary()
- throws RemoteException {
- runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
- Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID);
- }
-
- @Test
- public void updateActiveAndA11yFocusedWindow_a11yFocusEvent_multiDisplay_SecondaryToDefault()
- throws RemoteException {
- runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
- SECONDARY_DISPLAY_ID, Display.DEFAULT_DISPLAY);
- }
-
- private void runUpdateActiveAndA11yFocusedWindow_MultiDisplayTest(
- int initialDisplayId, int eventDisplayId) throws RemoteException {
- startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
- final int initialWindowId = getWindowIdFromWindowInfosForDisplay(
- initialDisplayId, DEFAULT_FOCUSED_INDEX);
- final int noUse = 0;
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- initialWindowId,
- AccessibilityNodeInfo.ROOT_NODE_ID,
- AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
- noUse);
- assertThat(mA11yWindowManager.getFocusedWindowId(
- AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(initialWindowId));
- Mockito.reset(mMockA11yEventSender);
-
- final int eventWindowId = getWindowIdFromWindowInfosForDisplay(
- eventDisplayId, DEFAULT_FOCUSED_INDEX);
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- eventWindowId,
- AccessibilityNodeInfo.ROOT_NODE_ID,
- AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
- noUse);
- assertThat(mA11yWindowManager.getFocusedWindowId(
- AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId));
- final ArgumentCaptor<AccessibilityEvent> captor =
- ArgumentCaptor.forClass(AccessibilityEvent.class);
- verify(mMockA11yEventSender, times(2))
- .sendAccessibilityEventForCurrentUserLocked(captor.capture());
- assertThat(captor.getAllValues().get(0),
- allOf(displayId(initialDisplayId),
- eventWindowId(initialWindowId),
- a11yWindowChanges(
- AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
- assertThat(captor.getAllValues().get(1),
- allOf(displayId(eventDisplayId),
- eventWindowId(eventWindowId),
- a11yWindowChanges(
- AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED)));
- }
-
- @Test
- public void updateActiveAndA11yFocusedWindow_clearA11yFocusEvent_shouldClearA11yFocus() {
- final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
- DEFAULT_FOCUSED_INDEX);
- final int currentA11yFocusedWindowId = mA11yWindowManager.getFocusedWindowId(
- AccessibilityNodeInfo.FOCUS_ACCESSIBILITY);
- assertThat(currentA11yFocusedWindowId, is(not(eventWindowId)));
-
- final int noUse = 0;
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- eventWindowId,
- AccessibilityNodeInfo.ROOT_NODE_ID,
- AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
- noUse);
- assertThat(mA11yWindowManager.getFocusedWindowId(
- AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(eventWindowId));
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- eventWindowId,
- AccessibilityNodeInfo.ROOT_NODE_ID,
- AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED,
- noUse);
- assertThat(mA11yWindowManager.getFocusedWindowId(
- AccessibilityNodeInfo.FOCUS_ACCESSIBILITY),
- is(AccessibilityWindowInfo.UNDEFINED_WINDOW_ID));
- }
-
- @Test
- public void onTouchInteractionEnd_shouldRollbackActiveWindow() {
- final int eventWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
- DEFAULT_FOCUSED_INDEX + 1);
- final int currentActiveWindowId = mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID);
- assertThat(currentActiveWindowId, is(not(eventWindowId)));
-
- final int noUse = 0;
- mA11yWindowManager.onTouchInteractionStart();
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- eventWindowId,
- noUse,
- AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
- noUse);
- assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(eventWindowId));
- // AccessibilityEventSender is invoked after active window changed. Reset it.
- Mockito.reset(mMockA11yEventSender);
-
- mA11yWindowManager.onTouchInteractionEnd();
- final ArgumentCaptor<AccessibilityEvent> captor =
- ArgumentCaptor.forClass(AccessibilityEvent.class);
- verify(mMockA11yEventSender, times(2))
- .sendAccessibilityEventForCurrentUserLocked(captor.capture());
- assertThat(captor.getAllValues().get(0),
- allOf(displayId(Display.DEFAULT_DISPLAY),
- eventWindowId(eventWindowId),
- a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
- assertThat(captor.getAllValues().get(1),
- allOf(displayId(Display.DEFAULT_DISPLAY),
- eventWindowId(currentActiveWindowId),
- a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ACTIVE)));
- }
-
- @Test
- public void onTouchInteractionEnd_noServiceInteractiveWindow_shouldClearA11yFocus()
- throws RemoteException {
- final IBinder defaultFocusWinToken =
- mWindows.get(Display.DEFAULT_DISPLAY).get(
- DEFAULT_FOCUSED_INDEX).getWindowInfo().token;
- final int defaultFocusWindowId = mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, defaultFocusWinToken);
- when(mMockWindowManagerInternal.getFocusedWindowTokenFromWindowStates())
- .thenReturn(defaultFocusWinToken);
- final int newFocusWindowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY,
- DEFAULT_FOCUSED_INDEX + 1);
- final IAccessibilityInteractionConnection mockNewFocusConnection =
- mA11yWindowManager.getConnectionLocked(
- USER_SYSTEM_ID, newFocusWindowId).getRemote();
-
- mA11yWindowManager.stopTrackingWindows(Display.DEFAULT_DISPLAY);
- final int noUse = 0;
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- defaultFocusWindowId,
- noUse,
- AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
- noUse);
- assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(defaultFocusWindowId));
- assertThat(mA11yWindowManager.getFocusedWindowId(AccessibilityNodeInfo.FOCUS_INPUT),
- is(defaultFocusWindowId));
-
- mA11yWindowManager.onTouchInteractionStart();
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- newFocusWindowId,
- noUse,
- AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
- noUse);
- mA11yWindowManager.updateActiveAndAccessibilityFocusedWindowLocked(USER_SYSTEM_ID,
- newFocusWindowId,
- AccessibilityNodeInfo.ROOT_NODE_ID,
- AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
- noUse);
- assertThat(mA11yWindowManager.getActiveWindowId(USER_SYSTEM_ID), is(newFocusWindowId));
- assertThat(mA11yWindowManager.getFocusedWindowId(
- AccessibilityNodeInfo.FOCUS_ACCESSIBILITY), is(newFocusWindowId));
-
- mA11yWindowManager.onTouchInteractionEnd();
- mHandler.sendLastMessage();
- verify(mockNewFocusConnection).clearAccessibilityFocus();
- }
-
- @Test
- public void getPictureInPictureWindow_shouldNotNull() {
- assertNull(mA11yWindowManager.getPictureInPictureWindowLocked());
- mWindows.get(Display.DEFAULT_DISPLAY).get(1).getWindowInfo().inPictureInPicture = true;
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- assertNotNull(mA11yWindowManager.getPictureInPictureWindowLocked());
- }
-
- @Test
- public void notifyOutsideTouch() throws RemoteException {
- final int targetWindowId =
- getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 1);
- final int outsideWindowId =
- getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
- final IAccessibilityInteractionConnection mockRemoteConnection =
- mA11yWindowManager.getConnectionLocked(
- USER_SYSTEM_ID, outsideWindowId).getRemote();
- mWindows.get(Display.DEFAULT_DISPLAY).get(0).getWindowInfo().hasFlagWatchOutsideTouch =
- true;
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, SEND_ON_WINDOW_CHANGES);
-
- mA11yWindowManager.notifyOutsideTouch(USER_SYSTEM_ID, targetWindowId);
- verify(mockRemoteConnection).notifyOutsideTouch();
- }
-
- @Test
- public void addAccessibilityInteractionConnection_profileUser_findInParentUser()
- throws RemoteException {
- final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
- false, USER_PROFILE);
- final int windowId = mA11yWindowManager.findWindowIdLocked(
- USER_PROFILE_PARENT, token.asBinder());
- assertTrue(windowId >= 0);
- }
-
- @Test
- public void getDisplayList() throws RemoteException {
- // Starts tracking window of second display.
- startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
-
- final ArrayList<Integer> displayList = mA11yWindowManager.getDisplayListLocked(
- DISPLAY_TYPE_DEFAULT);
- assertTrue(displayList.equals(mExpectedDisplayList));
- }
-
- @Test
- public void setAccessibilityWindowIdToSurfaceMetadata()
- throws RemoteException {
- final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
- true, USER_SYSTEM_ID);
- int windowId = -1;
- for (int i = 0; i < mA11yWindowTokens.size(); i++) {
- if (mA11yWindowTokens.valueAt(i).equals(token)) {
- windowId = mA11yWindowTokens.keyAt(i);
- }
- }
- assertNotEquals("Returned token is not found in mA11yWindowTokens", -1, windowId);
- verify(mMockWindowManagerInternal, times(1)).setAccessibilityIdToSurfaceMetadata(
- token.asBinder(), windowId);
-
- mA11yWindowManager.removeAccessibilityInteractionConnection(token);
- verify(mMockWindowManagerInternal, times(1)).setAccessibilityIdToSurfaceMetadata(
- token.asBinder(), -1);
- }
-
- @Test
- public void getHostTokenLocked_hierarchiesAreAssociated_shouldReturnHostToken() {
- mA11yWindowManager.associateLocked(mMockEmbeddedToken, mMockHostToken);
- final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockEmbeddedToken);
- assertEquals(hostToken, mMockHostToken);
- }
-
- @Test
- public void getHostTokenLocked_hierarchiesAreNotAssociated_shouldReturnNull() {
- final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockEmbeddedToken);
- assertNull(hostToken);
- }
-
- @Test
- public void getHostTokenLocked_embeddedHierarchiesAreDisassociated_shouldReturnNull() {
- mA11yWindowManager.associateLocked(mMockEmbeddedToken, mMockHostToken);
- mA11yWindowManager.disassociateLocked(mMockEmbeddedToken);
- final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockEmbeddedToken);
- assertNull(hostToken);
- }
-
- @Test
- public void getHostTokenLocked_hostHierarchiesAreDisassociated_shouldReturnNull() {
- mA11yWindowManager.associateLocked(mMockEmbeddedToken, mMockHostToken);
- mA11yWindowManager.disassociateLocked(mMockHostToken);
- final IBinder hostToken = mA11yWindowManager.getHostTokenLocked(mMockHostToken);
- assertNull(hostToken);
- }
-
- @Test
- public void getWindowIdLocked_windowIsRegistered_shouldReturnWindowId() {
- final int windowId = mA11yWindowManager.getWindowIdLocked(mMockHostToken);
- assertEquals(windowId, HOST_WINDOW_ID);
- }
-
- @Test
- public void getWindowIdLocked_windowIsNotRegistered_shouldReturnInvalidWindowId() {
- final int windowId = mA11yWindowManager.getWindowIdLocked(mMockInvalidToken);
- assertEquals(windowId, INVALID_ID);
- }
-
- @Test
- public void getTokenLocked_windowIsRegistered_shouldReturnToken() {
- final IBinder token = mA11yWindowManager.getLeashTokenLocked(HOST_WINDOW_ID);
- assertEquals(token, mMockHostToken);
- }
-
- @Test
- public void getTokenLocked_windowIsNotRegistered_shouldReturnNull() {
- final IBinder token = mA11yWindowManager.getLeashTokenLocked(OTHER_WINDOW_ID);
- assertNull(token);
- }
-
- @Test
- public void setAccessibilityWindowAttributes_windowIsNotRegistered_titleIsChanged() {
- final int windowId =
- getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
- final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
- layoutParams.accessibilityTitle = "accessibility window title";
- final AccessibilityWindowAttributes attributes = new AccessibilityWindowAttributes(
- layoutParams, new LocaleList());
-
- mA11yWindowManager.setAccessibilityWindowAttributes(Display.DEFAULT_DISPLAY, windowId,
- USER_SYSTEM_ID, attributes);
-
- final AccessibilityWindowInfo a11yWindow = mA11yWindowManager.findA11yWindowInfoByIdLocked(
- windowId);
- assertEquals(toString(layoutParams.accessibilityTitle), toString(a11yWindow.getTitle()));
- }
-
- @Test
- public void sendAccessibilityEventOnWindowRemoval() {
- final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
-
- // Removing index 0 because it's not focused, and avoids unnecessary layer change.
- final int windowId =
- getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
- windows.remove(0);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-
- final ArgumentCaptor<AccessibilityEvent> captor =
- ArgumentCaptor.forClass(AccessibilityEvent.class);
- verify(mMockA11yEventSender, times(1))
- .sendAccessibilityEventForCurrentUserLocked(captor.capture());
- assertThat(captor.getAllValues().get(0),
- allOf(displayId(Display.DEFAULT_DISPLAY),
- eventWindowId(windowId),
- a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_REMOVED)));
- }
-
- @Test
- public void sendAccessibilityEventOnWindowAddition() throws RemoteException {
- final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
-
- final IWindow token = addAccessibilityInteractionConnection(Display.DEFAULT_DISPLAY,
- false, USER_SYSTEM_ID);
- // Adding window to the front so that other windows' layer won't change.
- windows.add(0, createMockAccessibilityWindow(token, Display.DEFAULT_DISPLAY));
- final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-
- final ArgumentCaptor<AccessibilityEvent> captor =
- ArgumentCaptor.forClass(AccessibilityEvent.class);
- verify(mMockA11yEventSender, times(1))
- .sendAccessibilityEventForCurrentUserLocked(captor.capture());
- assertThat(captor.getAllValues().get(0),
- allOf(displayId(Display.DEFAULT_DISPLAY),
- eventWindowId(windowId),
- a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_ADDED)));
- }
-
- @Test
- public void sendAccessibilityEventOnWindowChange() {
- final ArrayList<AccessibilityWindow> windows = mWindows.get(Display.DEFAULT_DISPLAY);
- windows.get(0).getWindowInfo().title = "new title";
- final int windowId = getWindowIdFromWindowInfosForDisplay(Display.DEFAULT_DISPLAY, 0);
-
- onAccessibilityWindowsChanged(Display.DEFAULT_DISPLAY, FORCE_SEND);
-
- final ArgumentCaptor<AccessibilityEvent> captor =
- ArgumentCaptor.forClass(AccessibilityEvent.class);
- verify(mMockA11yEventSender, times(1))
- .sendAccessibilityEventForCurrentUserLocked(captor.capture());
- assertThat(captor.getAllValues().get(0),
- allOf(displayId(Display.DEFAULT_DISPLAY),
- eventWindowId(windowId),
- a11yWindowChanges(AccessibilityEvent.WINDOWS_CHANGE_TITLE)));
- }
-
- private void registerLeashedTokenAndWindowId() {
- mA11yWindowManager.registerIdLocked(mMockHostToken, HOST_WINDOW_ID);
- mA11yWindowManager.registerIdLocked(mMockEmbeddedToken, EMBEDDED_WINDOW_ID);
- }
-
- private void startTrackingPerDisplay(int displayId) throws RemoteException {
- ArrayList<AccessibilityWindow> windowsForDisplay = new ArrayList<>();
- // Adds RemoteAccessibilityConnection into AccessibilityWindowManager, and copy
- // mock window token into mA11yWindowTokens. Also, preparing WindowInfo mWindowInfos
- // for the test.
- for (int i = 0; i < NUM_GLOBAL_WINDOWS; i++) {
- final IWindow token = addAccessibilityInteractionConnection(displayId,
- true, USER_SYSTEM_ID);
- windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
-
- }
- for (int i = 0; i < NUM_APP_WINDOWS; i++) {
- final IWindow token = addAccessibilityInteractionConnection(displayId,
- false, USER_SYSTEM_ID);
- windowsForDisplay.add(createMockAccessibilityWindow(token, displayId));
- }
- // Sets up current focused window of display.
- // Each display has its own current focused window if config_perDisplayFocusEnabled is true.
- // Otherwise only default display needs to current focused window.
- if (mSupportPerDisplayFocus || displayId == Display.DEFAULT_DISPLAY) {
- windowsForDisplay.get(DEFAULT_FOCUSED_INDEX).getWindowInfo().focused = true;
- }
- // Turns on windows tracking, and update window info.
- mA11yWindowManager.startTrackingWindows(displayId, false);
- // Puts window lists into array.
- mWindows.put(displayId, windowsForDisplay);
- // Sets the default display is the top focused display and
- // its current focused window is the top focused window.
- if (displayId == Display.DEFAULT_DISPLAY) {
- setTopFocusedWindowAndDisplay(displayId, DEFAULT_FOCUSED_INDEX);
- }
- // Invokes callback for sending window lists to A11y framework.
- onAccessibilityWindowsChanged(displayId, FORCE_SEND);
-
- assertEquals(mA11yWindowManager.getWindowListLocked(displayId).size(),
- windowsForDisplay.size());
- }
-
- private WindowsForAccessibilityCallback getWindowsForAccessibilityCallbacks(int displayId) {
- ArgumentCaptor<WindowsForAccessibilityCallback> windowsForAccessibilityCallbacksCaptor =
- ArgumentCaptor.forClass(
- WindowsForAccessibilityCallback.class);
- verify(mMockWindowManagerInternal)
- .setWindowsForAccessibilityCallback(eq(displayId),
- windowsForAccessibilityCallbacksCaptor.capture());
- return windowsForAccessibilityCallbacksCaptor.getValue();
- }
-
- private IWindow addAccessibilityInteractionConnection(int displayId, boolean bGlobal,
- int userId) throws RemoteException {
- final IWindow mockWindowToken = Mockito.mock(IWindow.class);
- final IAccessibilityInteractionConnection mockA11yConnection = Mockito.mock(
- IAccessibilityInteractionConnection.class);
- final IBinder mockConnectionBinder = Mockito.mock(IBinder.class);
- final IBinder mockWindowBinder = Mockito.mock(IBinder.class);
- final IBinder mockLeashToken = Mockito.mock(IBinder.class);
- when(mockA11yConnection.asBinder()).thenReturn(mockConnectionBinder);
- when(mockWindowToken.asBinder()).thenReturn(mockWindowBinder);
- when(mMockA11ySecurityPolicy.isCallerInteractingAcrossUsers(userId))
- .thenReturn(bGlobal);
- when(mMockWindowManagerInternal.getDisplayIdForWindow(mockWindowBinder))
- .thenReturn(displayId);
-
- int windowId = mA11yWindowManager.addAccessibilityInteractionConnection(
- mockWindowToken, mockLeashToken, mockA11yConnection, PACKAGE_NAME, userId);
- mA11yWindowTokens.put(windowId, mockWindowToken);
- return mockWindowToken;
- }
-
- private int addAccessibilityInteractionConnection(int displayId, boolean bGlobal,
- IBinder leashToken, int userId) throws RemoteException {
- final IWindow mockWindowToken = Mockito.mock(IWindow.class);
- final IAccessibilityInteractionConnection mockA11yConnection = Mockito.mock(
- IAccessibilityInteractionConnection.class);
- final IBinder mockConnectionBinder = Mockito.mock(IBinder.class);
- final IBinder mockWindowBinder = Mockito.mock(IBinder.class);
- when(mockA11yConnection.asBinder()).thenReturn(mockConnectionBinder);
- when(mockWindowToken.asBinder()).thenReturn(mockWindowBinder);
- when(mMockA11ySecurityPolicy.isCallerInteractingAcrossUsers(userId))
- .thenReturn(bGlobal);
- when(mMockWindowManagerInternal.getDisplayIdForWindow(mockWindowBinder))
- .thenReturn(displayId);
-
- int windowId = mA11yWindowManager.addAccessibilityInteractionConnection(
- mockWindowToken, leashToken, mockA11yConnection, PACKAGE_NAME, userId);
- mA11yWindowTokens.put(windowId, mockWindowToken);
- return windowId;
- }
-
- private int getWindowIdFromWindowInfosForDisplay(int displayId, int index) {
- final IBinder windowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
- return mA11yWindowManager.findWindowIdLocked(
- USER_SYSTEM_ID, windowToken);
- }
-
- private void setTopFocusedWindowAndDisplay(int displayId, int index) {
- // Sets the top focus window.
- mTopFocusedWindowToken = mWindows.get(displayId).get(index).getWindowInfo().token;
- // Sets the top focused display.
- mTopFocusedDisplayId = displayId;
- }
-
- private void onAccessibilityWindowsChanged(int displayId, boolean forceSend) {
- WindowsForAccessibilityCallback callbacks = mCallbackOfWindows.get(displayId);
- if (callbacks == null) {
- callbacks = getWindowsForAccessibilityCallbacks(displayId);
- mCallbackOfWindows.put(displayId, callbacks);
- }
- callbacks.onAccessibilityWindowsChanged(forceSend, mTopFocusedDisplayId,
- mTopFocusedWindowToken, new Point(SCREEN_WIDTH, SCREEN_HEIGHT),
- mWindows.get(displayId));
- }
-
- private void changeFocusedWindowOnDisplayPerDisplayFocusConfig(
- int changeFocusedDisplayId, int newFocusedWindowIndex, int oldTopFocusedDisplayId,
- int oldFocusedWindowIndex) {
- if (mSupportPerDisplayFocus) {
- // Gets the old focused window of display which wants to change focused window.
- WindowInfo focusedWindowInfo =
- mWindows.get(changeFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
- // Resets the focus of old focused window.
- focusedWindowInfo.focused = false;
- // Gets the new window of display which wants to change focused window.
- focusedWindowInfo =
- mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
- // Sets the focus of new focused window.
- focusedWindowInfo.focused = true;
- } else {
- // Gets the window of display which wants to change focused window.
- WindowInfo focusedWindowInfo =
- mWindows.get(changeFocusedDisplayId).get(newFocusedWindowIndex).getWindowInfo();
- // Sets the focus of new focused window.
- focusedWindowInfo.focused = true;
- // Gets the old focused window of old top focused display.
- focusedWindowInfo =
- mWindows.get(oldTopFocusedDisplayId).get(oldFocusedWindowIndex).getWindowInfo();
- // Resets the focus of old focused window.
- focusedWindowInfo.focused = false;
- // Changes the top focused display and window.
- setTopFocusedWindowAndDisplay(changeFocusedDisplayId, newFocusedWindowIndex);
- }
- }
-
- private AccessibilityWindow createMockAccessibilityWindow(IWindow windowToken, int displayId) {
- final WindowInfo windowInfo = WindowInfo.obtain();
- windowInfo.type = WindowManager.LayoutParams.TYPE_APPLICATION;
- windowInfo.token = windowToken.asBinder();
-
- final AccessibilityWindow window = Mockito.mock(AccessibilityWindow.class);
- when(window.getWindowInfo()).thenReturn(windowInfo);
- when(window.isFocused()).thenAnswer(invocation -> windowInfo.focused);
- when(window.isTouchable()).thenReturn(true);
- when(window.getType()).thenReturn(windowInfo.type);
-
- setRegionForMockAccessibilityWindow(window, nextToucableRegion(displayId));
- return window;
- }
-
- private void setRegionForMockAccessibilityWindow(AccessibilityWindow window, Region region) {
- doAnswer(invocation -> {
- ((Region) invocation.getArgument(0)).set(region);
- return null;
- }).when(window).getTouchableRegionInScreen(any(Region.class));
- doAnswer(invocation -> {
- ((Region) invocation.getArgument(0)).set(region);
- return null;
- }).when(window).getTouchableRegionInWindow(any(Region.class));
- }
-
- private Region nextToucableRegion(int displayId) {
- final int topLeft = mNextRegionOffsets.get(displayId, 0);
- final int bottomRight = topLeft + 100;
- mNextRegionOffsets.put(displayId, topLeft + 10);
- return new Region(topLeft, topLeft, bottomRight, bottomRight);
- }
-
- @Nullable
- private static String toString(@Nullable CharSequence cs) {
- return cs == null ? null : cs.toString();
- }
-
- static class DisplayIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
- private final int mDisplayId;
-
- DisplayIdMatcher(int displayId) {
- super();
- mDisplayId = displayId;
- }
-
- static DisplayIdMatcher displayId(int displayId) {
- return new DisplayIdMatcher(displayId);
- }
-
- @Override
- protected boolean matchesSafely(AccessibilityEvent event) {
- return event.getDisplayId() == mDisplayId;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("Matching to displayId " + mDisplayId);
- }
- }
-
- static class EventWindowIdMatcher extends TypeSafeMatcher<AccessibilityEvent> {
- private int mWindowId;
-
- EventWindowIdMatcher(int windowId) {
- super();
- mWindowId = windowId;
- }
-
- static EventWindowIdMatcher eventWindowId(int windowId) {
- return new EventWindowIdMatcher(windowId);
- }
-
- @Override
- protected boolean matchesSafely(AccessibilityEvent event) {
- return event.getWindowId() == mWindowId;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("Matching to windowId " + mWindowId);
- }
- }
-
- static class WindowChangesMatcher extends TypeSafeMatcher<AccessibilityEvent> {
- private int mWindowChanges;
-
- WindowChangesMatcher(int windowChanges) {
- super();
- mWindowChanges = windowChanges;
- }
-
- static WindowChangesMatcher a11yWindowChanges(int windowChanges) {
- return new WindowChangesMatcher(windowChanges);
- }
-
- @Override
- protected boolean matchesSafely(AccessibilityEvent event) {
- return event.getWindowChanges() == mWindowChanges;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("Matching to window changes " + mWindowChanges);
- }
- }
-
- static class WindowIdMatcher extends TypeSafeMatcher<AccessibilityWindowInfo> {
- private final int mWindowId;
-
- WindowIdMatcher(int windowId) {
- super();
- mWindowId = windowId;
- }
-
- static WindowIdMatcher windowId(int windowId) {
- return new WindowIdMatcher(windowId);
- }
-
- @Override
- protected boolean matchesSafely(AccessibilityWindowInfo window) {
- return window.getId() == mWindowId;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("Matching to windowId " + mWindowId);
- }
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index cf5dc4bec71c..a7bf3e194dd9 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -4404,6 +4404,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
+ @Ignore("b/277916462")
public void testSetAutoTimeEnabledModifiesSetting() throws Exception {
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
setupDeviceOwner();
@@ -4415,6 +4416,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
+ @Ignore("b/277916462")
public void testSetAutoTimeEnabledWithPOOnUser0() throws Exception {
mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
setupProfileOwnerOnUser0();
@@ -4434,7 +4436,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
}
@Test
- @Ignore("b/359188869")
+ @Ignore("b/277916462")
public void testSetAutoTimeEnabledWithPOOfOrganizationOwnedDevice() throws Exception {
setupProfileOwner();
configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 0816e7b61165..5be4490e67ef 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -118,6 +118,7 @@ public class HdmiCecLocalDeviceTvTest {
private boolean mDisableCecOnStandbyByLowEnergyMode;
private boolean mWasCecDisabledOnStandbyByLowEnergyMode;
private boolean mUseHdmiCecPowerStatusController;
+ private boolean mUserEnabledCecInOfflineMode;
private class DeviceEventListener {
private HdmiDeviceInfo mDevice;
@@ -250,6 +251,11 @@ public class HdmiCecLocalDeviceTvTest {
protected void setWasCecDisabledOnStandbyByLowEnergyMode(boolean value) {
mWasCecDisabledOnStandbyByLowEnergyMode = value;
}
+
+ @Override
+ protected boolean userEnabledCecInOfflineMode() {
+ return mUserEnabledCecInOfflineMode;
+ }
};
mHdmiControlService.setIoLooper(mMyLooper);
@@ -298,6 +304,7 @@ public class HdmiCecLocalDeviceTvTest {
mWasCecDisabledOnStandbyByLowEnergyMode = false;
mDisableCecOnStandbyByLowEnergyMode = false;
mUseHdmiCecPowerStatusController = false;
+ mUserEnabledCecInOfflineMode = false;
mNativeWrapper.clearResultMessages();
}
@@ -2400,6 +2407,32 @@ public class HdmiCecLocalDeviceTvTest {
assertTrue(mVendorCommandListeners.contains(vendorCommandListenerInvocationSettingChange));
}
+ @Test
+ public void lowEnergyMode_userEnabledCecInOfflineMode_onStandby_cecStaysEnabled() {
+ mDisableCecOnStandbyByLowEnergyMode = true;
+ mUseHdmiCecPowerStatusController = true;
+ mUserEnabledCecInOfflineMode = true;
+ mPowerManager.setIsLowPowerStandbyEnabled(true);
+
+ assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED),
+ HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+ mHdmiControlService.onStandby(STANDBY_SCREEN_OFF);
+ mTestLooper.dispatchAll();
+
+ assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED),
+ HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+ assertFalse(mWasCecDisabledOnStandbyByLowEnergyMode);
+ mHdmiControlService.onWakeUp(WAKE_UP_SCREEN_ON);
+ mTestLooper.dispatchAll();
+
+ assertEquals(mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().getIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED),
+ HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
+ assertFalse(mWasCecDisabledOnStandbyByLowEnergyMode);
+ }
+
protected static class MockTvDevice extends HdmiCecLocalDeviceTv {
MockTvDevice(HdmiControlService service) {
super(service);
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index b2a7d20fb948..3ced56a04138 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -67,10 +67,12 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Rect;
import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionCallback;
import android.media.projection.IMediaProjectionWatcherCallback;
import android.media.projection.ReviewGrantedConsentResult;
+import android.media.projection.StopReason;
import android.os.Binder;
import android.os.IBinder;
import android.os.Looper;
@@ -549,7 +551,7 @@ public class MediaProjectionManagerServiceTest {
MediaProjectionManagerService.MediaProjection projection =
startProjectionPreconditions(service);
- projection.stop();
+ projection.stop(StopReason.STOP_UNKNOWN);
verifyZeroInteractions(mMediaProjectionMetricsLogger);
}
@@ -562,10 +564,10 @@ public class MediaProjectionManagerServiceTest {
startProjectionPreconditions(service);
projection.start(mIMediaProjectionCallback);
- projection.stop();
+ final @StopReason int stopReason = StopReason.STOP_UNKNOWN;
+ projection.stop(stopReason);
- verify(mMediaProjectionMetricsLogger)
- .logStopped(UID, TARGET_UID_UNKNOWN);
+ verify(mMediaProjectionMetricsLogger).logStopped(UID, TARGET_UID_UNKNOWN, stopReason);
}
@Test
@@ -580,15 +582,16 @@ public class MediaProjectionManagerServiceTest {
.setContentRecordingSession(any(ContentRecordingSession.class));
service.setContentRecordingSession(DISPLAY_SESSION);
- projection.stop();
+ final @StopReason int stopReason = StopReason.STOP_UNKNOWN;
+ projection.stop(stopReason);
- verify(mMediaProjectionMetricsLogger)
- .logStopped(UID, TARGET_UID_FULL_SCREEN);
+ verify(mMediaProjectionMetricsLogger).logStopped(UID, TARGET_UID_FULL_SCREEN, stopReason);
}
@Test
public void stop_taskSession_logsHostUidAndTargetUid() throws Exception {
int targetUid = 1234;
+ int stopReason = StopReason.STOP_UNKNOWN;
MediaProjectionManagerService service =
new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
MediaProjectionManagerService.MediaProjection projection =
@@ -601,9 +604,9 @@ public class MediaProjectionManagerServiceTest {
taskSession.setTargetUid(targetUid);
service.setContentRecordingSession(taskSession);
- projection.stop();
+ projection.stop(stopReason);
- verify(mMediaProjectionMetricsLogger).logStopped(UID, targetUid);
+ verify(mMediaProjectionMetricsLogger).logStopped(UID, targetUid, stopReason);
}
@Test
@@ -638,7 +641,7 @@ public class MediaProjectionManagerServiceTest {
projection.start(mIMediaProjectionCallback);
assertThat(projection.isValid()).isTrue();
- projection.stop();
+ projection.stop(StopReason.STOP_UNKNOWN);
// Second start - so not valid.
projection.start(mIMediaProjectionCallback);
@@ -692,7 +695,7 @@ public class MediaProjectionManagerServiceTest {
MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(
service);
projection.start(mIMediaProjectionCallback);
- projection.stop();
+ projection.stop(StopReason.STOP_UNKNOWN);
// Second start - so not valid.
projection.start(mIMediaProjectionCallback);
@@ -708,7 +711,7 @@ public class MediaProjectionManagerServiceTest {
MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions(
service);
projection.start(mIMediaProjectionCallback);
- projection.stop();
+ projection.stop(StopReason.STOP_UNKNOWN);
// Second start - so not valid.
projection.start(mIMediaProjectionCallback);
@@ -947,6 +950,26 @@ public class MediaProjectionManagerServiceTest {
projection.uid, targetUid, WINDOWING_MODE_MULTI_WINDOW);
}
+ @Test
+ public void notifyCaptureBoundsChanged_forwardsToLoggerAndResizeCallbacks() throws Exception {
+ int targetUid = 123;
+ mService =
+ new MediaProjectionManagerService(mContext, mMediaProjectionMetricsLoggerInjector);
+
+ ContentRecordingSession taskSession = createTaskSession(mock(IBinder.class));
+ taskSession.setTargetUid(targetUid);
+ mService.setContentRecordingSession(taskSession);
+
+ MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
+ projection.start(mIMediaProjectionCallback);
+
+ Rect newBounds = new Rect(0, 0, 1000, 2000);
+ mService.notifyCaptureBoundsChanged(RECORD_CONTENT_TASK, targetUid, newBounds);
+
+ verify(mMediaProjectionMetricsLogger)
+ .logChangedCaptureBounds(RECORD_CONTENT_TASK, projection.uid, targetUid, newBounds);
+ }
+
/**
* Executes and validates scenario where the consent result indicates the projection ends.
*/
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java
index 72ce9fe9a23f..c727bb6bbf7d 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionMetricsLoggerTest.java
@@ -32,6 +32,17 @@ import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_DEVICE_LOCK;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_ERROR;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_FOREGROUND_SERVICE_CHANGE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_HOST_APP_STOP;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_MEDIA_ROUTE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_PROJECTION;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_QS_TILE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_STATUS_BAR_CHIP_STOP;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_TASK_APP_CLOSE;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_USER_SWITCH;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_APP_TASK;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_DISPLAY;
import static com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_TARGET_CHANGED__TARGET_TYPE__TARGET_TYPE_UNKNOWN;
@@ -46,6 +57,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.media.projection.StopReason;
import android.platform.test.annotations.Presubmit;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -81,6 +93,7 @@ public class MediaProjectionMetricsLoggerTest {
private static final int TEST_WINDOWING_MODE = 987;
private static final int TEST_CONTENT_TO_RECORD = 654;
+ private static final int TEST_STOP_SOURCE = 321;
@Mock private FrameworkStatsLogWrapper mFrameworkStatsLogWrapper;
@Mock private MediaProjectionSessionIdGenerator mSessionIdGenerator;
@@ -136,6 +149,14 @@ public class MediaProjectionMetricsLoggerTest {
}
@Test
+ public void logInitiated_logsUnknownStopSource() {
+ mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
+
+ verifyStopSourceLogged(
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+ }
+
+ @Test
public void logInitiated_noPreviousSession_logsUnknownTimeSinceLastActive() {
when(mTimestampStore.timeSinceLastActiveSession()).thenReturn(null);
@@ -177,7 +198,7 @@ public class MediaProjectionMetricsLoggerTest {
@Test
public void logStopped_logsStateChangedAtomId() {
- mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
verifyStateChangedAtomIdLogged();
}
@@ -187,42 +208,49 @@ public class MediaProjectionMetricsLoggerTest {
int currentSessionId = 987;
when(mSessionIdGenerator.getCurrentSessionId()).thenReturn(currentSessionId);
- mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
verifySessionIdLogged(currentSessionId);
}
@Test
public void logStopped_logsStateStopped() {
- mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
verifyStateLogged(MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED);
}
@Test
public void logStopped_logsHostUid() {
- mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
verifyStateChangedHostUidLogged(TEST_HOST_UID);
}
@Test
public void logStopped_logsTargetUid() {
- mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
verifyStageChangedTargetUidLogged(TEST_TARGET_UID);
}
@Test
+ public void logStopped_logsStopSource() {
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, StopReason.STOP_UNKNOWN);
+
+ verifyStopSourceLogged(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+ }
+
+ @Test
public void logStopped_logsUnknownTimeSinceLastActive() {
- mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
verifyTimeSinceLastActiveSessionLogged(-1);
}
@Test
public void logStopped_logsUnknownSessionCreationSource() {
- mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
verifyCreationSourceLogged(
MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN);
@@ -230,7 +258,7 @@ public class MediaProjectionMetricsLoggerTest {
@Test
public void logStopped_logsPreviousState() {
- mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
verifyPreviousStateLogged(
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_UNKNOWN);
@@ -238,7 +266,7 @@ public class MediaProjectionMetricsLoggerTest {
verifyPreviousStateLogged(
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_STOPPED);
- mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE);
+ mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE, TEST_STOP_SOURCE);
verifyPreviousStateLogged(
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED);
}
@@ -247,14 +275,14 @@ public class MediaProjectionMetricsLoggerTest {
public void logStopped_capturingWasInProgress_registersActiveSessionEnded() {
mLogger.logInProgress(TEST_HOST_UID, TEST_TARGET_UID);
- mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
verify(mTimestampStore).registerActiveSessionEnded();
}
@Test
public void logStopped_capturingWasNotInProgress_doesNotRegistersActiveSessionEnded() {
- mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID);
+ mLogger.logStopped(TEST_HOST_UID, TEST_TARGET_UID, TEST_STOP_SOURCE);
verify(mTimestampStore, never()).registerActiveSessionEnded();
}
@@ -314,6 +342,14 @@ public class MediaProjectionMetricsLoggerTest {
}
@Test
+ public void logInProgress_logsUnknownSessionStopSource() {
+ mLogger.logInProgress(TEST_HOST_UID, TEST_TARGET_UID);
+
+ verifyStopSourceLogged(
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+ }
+
+ @Test
public void logInProgress_logsPreviousState() {
mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
verifyPreviousStateLogged(
@@ -323,7 +359,7 @@ public class MediaProjectionMetricsLoggerTest {
verifyPreviousStateLogged(
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED);
- mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE);
+ mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE, TEST_STOP_SOURCE);
verifyPreviousStateLogged(
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_CAPTURING_IN_PROGRESS);
@@ -387,6 +423,14 @@ public class MediaProjectionMetricsLoggerTest {
}
@Test
+ public void logPermissionRequestDisplayed_logsUnknownSessionStopSource() {
+ mLogger.logPermissionRequestDisplayed(TEST_HOST_UID);
+
+ verifyStopSourceLogged(
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+ }
+
+ @Test
public void logPermissionRequestDisplayed_logsPreviousState() {
mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
verifyPreviousStateLogged(
@@ -396,7 +440,7 @@ public class MediaProjectionMetricsLoggerTest {
verifyPreviousStateLogged(
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED);
- mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE);
+ mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE, TEST_STOP_SOURCE);
verifyPreviousStateLogged(
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_PERMISSION_REQUEST_DISPLAYED);
@@ -460,6 +504,14 @@ public class MediaProjectionMetricsLoggerTest {
}
@Test
+ public void logAppSelectorDisplayed_logsUnknownSessionStopSource() {
+ mLogger.logAppSelectorDisplayed(TEST_HOST_UID);
+
+ verifyStopSourceLogged(
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+ }
+
+ @Test
public void logAppSelectorDisplayed_logsPreviousState() {
mLogger.logInitiated(TEST_HOST_UID, TEST_CREATION_SOURCE);
verifyPreviousStateLogged(
@@ -469,7 +521,7 @@ public class MediaProjectionMetricsLoggerTest {
verifyPreviousStateLogged(
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_INITIATED);
- mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE);
+ mLogger.logStopped(TEST_HOST_UID, TEST_CREATION_SOURCE, TEST_STOP_SOURCE);
verifyPreviousStateLogged(
MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_APP_SELECTOR_DISPLAYED);
@@ -536,6 +588,14 @@ public class MediaProjectionMetricsLoggerTest {
}
@Test
+ public void logProjectionPermissionRequestCancelled_logsUnknownStopSource() {
+ mLogger.logProjectionPermissionRequestCancelled(TEST_HOST_UID);
+
+ verifyStopSourceLogged(
+ MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+ }
+
+ @Test
public void logWindowingModeChanged_logsTargetChangedAtomId() {
mLogger.logChangedWindowingMode(
TEST_CONTENT_TO_RECORD, TEST_HOST_UID, TEST_TARGET_UID, TEST_WINDOWING_MODE);
@@ -614,6 +674,42 @@ public class MediaProjectionMetricsLoggerTest {
.isEqualTo(MEDIA_PROJECTION_TARGET_CHANGED__TARGET_WINDOWING_MODE__WINDOWING_MODE_UNKNOWN);
}
+ @Test
+ public void testStopReasonToSessionStopSource() {
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_HOST_APP))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_HOST_APP_STOP);
+
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_TARGET_REMOVED))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_TASK_APP_CLOSE);
+
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_DEVICE_LOCKED))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_DEVICE_LOCK);
+
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_PRIVACY_CHIP))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_STATUS_BAR_CHIP_STOP);
+
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_QS_TILE))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_QS_TILE);
+
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_USER_SWITCH))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_USER_SWITCH);
+
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_FOREGROUND_SERVICE_CHANGE))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_FOREGROUND_SERVICE_CHANGE);
+
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_NEW_PROJECTION))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_PROJECTION);
+
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_NEW_MEDIA_ROUTE))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_NEW_MEDIA_ROUTE);
+
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_ERROR))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_ERROR);
+
+ mExpect.that(mLogger.stopReasonToSessionStopSource(StopReason.STOP_UNKNOWN))
+ .isEqualTo(MEDIA_PROJECTION_STATE_CHANGED__STOP_SOURCE__STOP_SOURCE_UNKNOWN);
+ }
+
private void verifyStateChangedAtomIdLogged() {
verify(mFrameworkStatsLogWrapper)
.writeStateChanged(
@@ -624,7 +720,8 @@ public class MediaProjectionMetricsLoggerTest {
/* hostUid= */ anyInt(),
/* targetUid= */ anyInt(),
/* timeSinceLastActive= */ anyInt(),
- /* creationSource= */ anyInt());
+ /* creationSource= */ anyInt(),
+ /* stopSource= */ anyInt());
}
private void verifyStateLogged(int state) {
@@ -637,7 +734,8 @@ public class MediaProjectionMetricsLoggerTest {
/* hostUid= */ anyInt(),
/* targetUid= */ anyInt(),
/* timeSinceLastActive= */ anyInt(),
- /* creationSource= */ anyInt());
+ /* creationSource= */ anyInt(),
+ /* stopSource= */ anyInt());
}
private void verifyStateChangedHostUidLogged(int hostUid) {
@@ -650,7 +748,8 @@ public class MediaProjectionMetricsLoggerTest {
eq(hostUid),
/* targetUid= */ anyInt(),
/* timeSinceLastActive= */ anyInt(),
- /* creationSource= */ anyInt());
+ /* creationSource= */ anyInt(),
+ /* stopSource= */ anyInt());
}
private void verifyCreationSourceLogged(int creationSource) {
@@ -663,7 +762,22 @@ public class MediaProjectionMetricsLoggerTest {
/* hostUid= */ anyInt(),
/* targetUid= */ anyInt(),
/* timeSinceLastActive= */ anyInt(),
- eq(creationSource));
+ eq(creationSource),
+ /* stopSource= */ anyInt());
+ }
+
+ private void verifyStopSourceLogged(int stopSource) {
+ verify(mFrameworkStatsLogWrapper)
+ .writeStateChanged(
+ /* code= */ anyInt(),
+ /* sessionId= */ anyInt(),
+ /* state= */ anyInt(),
+ /* previousState= */ anyInt(),
+ /* hostUid= */ anyInt(),
+ /* targetUid= */ anyInt(),
+ /* timeSinceLastActive= */ anyInt(),
+ /* stopSource= */ anyInt(),
+ eq(stopSource));
}
private void verifyStageChangedTargetUidLogged(int targetUid) {
@@ -676,7 +790,8 @@ public class MediaProjectionMetricsLoggerTest {
/* hostUid= */ anyInt(),
eq(targetUid),
/* timeSinceLastActive= */ anyInt(),
- /* creationSource= */ anyInt());
+ /* creationSource= */ anyInt(),
+ /* stopSource= */ anyInt());
}
private void verifyTimeSinceLastActiveSessionLogged(int timeSinceLastActiveSession) {
@@ -689,7 +804,8 @@ public class MediaProjectionMetricsLoggerTest {
/* hostUid= */ anyInt(),
/* targetUid= */ anyInt(),
/* timeSinceLastActive= */ eq(timeSinceLastActiveSession),
- /* creationSource= */ anyInt());
+ /* creationSource= */ anyInt(),
+ /* stopSource= */ anyInt());
}
private void verifySessionIdLogged(int newSessionId) {
@@ -702,7 +818,8 @@ public class MediaProjectionMetricsLoggerTest {
/* hostUid= */ anyInt(),
/* targetUid= */ anyInt(),
/* timeSinceLastActive= */ anyInt(),
- /* creationSource= */ anyInt());
+ /* creationSource= */ anyInt(),
+ /* stopSource= */ anyInt());
}
private void verifyPreviousStateLogged(int previousState) {
@@ -715,7 +832,8 @@ public class MediaProjectionMetricsLoggerTest {
/* hostUid= */ anyInt(),
/* targetUid= */ anyInt(),
/* timeSinceLastActive= */ anyInt(),
- /* creationSource= */ anyInt());
+ /* creationSource= */ anyInt(),
+ /* stopSource= */ anyInt());
}
private void verifyTargetChangedAtomIdLogged() {
@@ -726,7 +844,12 @@ public class MediaProjectionMetricsLoggerTest {
/* targetType= */ anyInt(),
/* hostUid= */ anyInt(),
/* targetUid= */ anyInt(),
- /* targetWindowingMode= */ anyInt());
+ /* targetWindowingMode= */ anyInt(),
+ /* width= */ anyInt(),
+ /* height= */ anyInt(),
+ /* centerX= */ anyInt(),
+ /* centerY= */ anyInt(),
+ /* targetChangeType= */ anyInt());
}
private void verifyTargetTypeLogged(int targetType) {
@@ -737,7 +860,12 @@ public class MediaProjectionMetricsLoggerTest {
eq(targetType),
/* hostUid= */ anyInt(),
/* targetUid= */ anyInt(),
- /* targetWindowingMode= */ anyInt());
+ /* targetWindowingMode= */ anyInt(),
+ /* width= */ anyInt(),
+ /* height= */ anyInt(),
+ /* centerX= */ anyInt(),
+ /* centerY= */ anyInt(),
+ /* targetChangeType= */ anyInt());
}
private void verifyTargetChangedHostUidLogged(int hostUid) {
@@ -748,7 +876,12 @@ public class MediaProjectionMetricsLoggerTest {
/* targetType= */ anyInt(),
eq(hostUid),
/* targetUid= */ anyInt(),
- /* targetWindowingMode= */ anyInt());
+ /* targetWindowingMode= */ anyInt(),
+ /* width= */ anyInt(),
+ /* height= */ anyInt(),
+ /* centerX= */ anyInt(),
+ /* centerY= */ anyInt(),
+ /* targetChangeType= */ anyInt());
}
private void verifyTargetChangedTargetUidLogged(int targetUid) {
@@ -759,7 +892,12 @@ public class MediaProjectionMetricsLoggerTest {
/* targetType= */ anyInt(),
/* hostUid= */ anyInt(),
eq(targetUid),
- /* targetWindowingMode= */ anyInt());
+ /* targetWindowingMode= */ anyInt(),
+ /* width= */ anyInt(),
+ /* height= */ anyInt(),
+ /* centerX= */ anyInt(),
+ /* centerY= */ anyInt(),
+ /* targetChangeType= */ anyInt());
}
private void verifyWindowingModeLogged(int targetWindowingMode) {
@@ -770,6 +908,11 @@ public class MediaProjectionMetricsLoggerTest {
/* targetType= */ anyInt(),
/* hostUid= */ anyInt(),
/* targetUid= */ anyInt(),
- eq(targetWindowingMode));
+ eq(targetWindowingMode),
+ /* width= */ anyInt(),
+ /* height= */ anyInt(),
+ /* centerX= */ anyInt(),
+ /* centerY= */ anyInt(),
+ /* targetChangeType= */ anyInt());
}
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/SystemZenRulesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/SystemZenRulesTest.java
index 4d82c3ccf4a1..949c5e2e1b0a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/SystemZenRulesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/SystemZenRulesTest.java
@@ -69,6 +69,8 @@ public class SystemZenRulesTest extends UiServiceTestCase {
R.string.zen_mode_trigger_summary_range_symbol_combination, "%1$s-%2$s");
mContext.getOrCreateTestableResources().addOverride(
R.string.zen_mode_trigger_summary_divider_text, ",");
+ mContext.getOrCreateTestableResources().addOverride(
+ R.string.zen_mode_trigger_summary_combined, "%1$s,%2$s");
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
index c51261f40ed5..76b994d013f3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -49,6 +49,7 @@ import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
+import android.media.projection.StopReason;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.view.ContentRecordingSession;
@@ -213,7 +214,7 @@ public class ContentRecorderTests extends WindowTestsBase {
mContentRecorder.setContentRecordingSession(session);
mContentRecorder.updateRecording();
assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
- verify(mMediaProjectionManagerWrapper).stopActiveProjection();
+ verify(mMediaProjectionManagerWrapper).stopActiveProjection(StopReason.STOP_ERROR);
}
@Test
@@ -225,7 +226,7 @@ public class ContentRecorderTests extends WindowTestsBase {
mContentRecorder.setContentRecordingSession(invalidTaskSession);
mContentRecorder.updateRecording();
assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
- verify(mMediaProjectionManagerWrapper).stopActiveProjection();
+ verify(mMediaProjectionManagerWrapper).stopActiveProjection(StopReason.STOP_ERROR);
}
@Test
@@ -310,8 +311,7 @@ public class ContentRecorderTests extends WindowTestsBase {
mVirtualDisplayContent.getConfiguration().orientation, WINDOWING_MODE_FULLSCREEN);
// No resize is issued, only the initial transformations when we started recording.
- verify(mTransaction).setPosition(eq(mRecordedSurface), anyFloat(),
- anyFloat());
+ verify(mTransaction).setPosition(eq(mRecordedSurface), anyFloat(), anyFloat());
verify(mTransaction).setMatrix(eq(mRecordedSurface), anyFloat(), anyFloat(),
anyFloat(), anyFloat());
}
@@ -386,19 +386,18 @@ public class ContentRecorderTests extends WindowTestsBase {
// WHEN a configuration change arrives, and the recorded content is a different size.
Configuration configuration = mTask.getConfiguration();
- configuration.windowConfiguration.setBounds(new Rect(0, 0, recordedWidth, recordedHeight));
- configuration.windowConfiguration.setAppBounds(
- new Rect(0, 0, recordedWidth, recordedHeight));
+ Rect newBounds = new Rect(0, 0, recordedWidth, recordedHeight);
+ configuration.windowConfiguration.setBounds(newBounds);
+ configuration.windowConfiguration.setAppBounds(newBounds);
mTask.onConfigurationChanged(configuration);
assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
// THEN content in the captured DisplayArea is scaled to fit the surface size.
- verify(mTransaction, atLeastOnce()).setMatrix(eq(mRecordedSurface), anyFloat(), eq(0f),
- eq(0f),
- anyFloat());
+ verify(mTransaction, atLeastOnce()).setMatrix(
+ eq(mRecordedSurface), anyFloat(), eq(0f), eq(0f), anyFloat());
// THEN the resize callback is notified.
- verify(mMediaProjectionManagerWrapper).notifyActiveProjectionCapturedContentResized(
- recordedWidth, recordedHeight);
+ verify(mMediaProjectionManagerWrapper).notifyCaptureBoundsChanged(
+ mTaskSession.getContentToRecord(), mTaskSession.getTargetUid(), newBounds);
}
@Test
@@ -649,7 +648,7 @@ public class ContentRecorderTests extends WindowTestsBase {
mTask.removeImmediately();
- verify(mMediaProjectionManagerWrapper).stopActiveProjection();
+ verify(mMediaProjectionManagerWrapper).stopActiveProjection(StopReason.STOP_TARGET_REMOVED);
}
@Test
@@ -684,8 +683,8 @@ public class ContentRecorderTests extends WindowTestsBase {
int xInset = (mSurfaceSize.x - scaledWidth) / 2;
verify(mTransaction, atLeastOnce()).setPosition(mRecordedSurface, xInset, 0);
// THEN the resize callback is notified.
- verify(mMediaProjectionManagerWrapper).notifyActiveProjectionCapturedContentResized(
- displayAreaBounds.width(), displayAreaBounds.height());
+ verify(mMediaProjectionManagerWrapper).notifyCaptureBoundsChanged(
+ mDisplaySession.getContentToRecord(), mDisplaySession.getTargetUid(), displayAreaBounds);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java b/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java
index c9c31dfe5307..a0f4ae77452c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DeferredDisplayUpdaterDiffTest.java
@@ -239,6 +239,9 @@ public class DeferredDisplayUpdaterDiffTest {
} else if (type.equals(FrameRateCategoryRate.class)) {
field.set(first, new FrameRateCategoryRate(16666667, 11111111));
field.set(second, new FrameRateCategoryRate(11111111, 8333333));
+ } else if (type.isArray() && type.getComponentType().equals(float.class)) {
+ field.set(first, new float[]{60.0f});
+ field.set(second, new float[]{120.0f});
} else {
throw new IllegalArgumentException("Field " + field
+ " is not supported by this test, please add implementation of setting "
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
index c8fc4822259e..63973345b5fb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationImmersiveAppCompatPolicyTests.java
@@ -20,16 +20,19 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
import android.platform.test.annotations.Presubmit;
import android.view.Surface;
@@ -54,6 +57,7 @@ public class DisplayRotationImmersiveAppCompatPolicyTests extends WindowTestsBas
private DisplayRotationImmersiveAppCompatPolicy mPolicy;
+ private DisplayRotation mMockDisplayRotation;
private AppCompatConfiguration mMockAppCompatConfiguration;
private ActivityRecord mMockActivityRecord;
private Task mMockTask;
@@ -98,6 +102,7 @@ public class DisplayRotationImmersiveAppCompatPolicyTests extends WindowTestsBas
when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_90)).thenReturn(true);
when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_180)).thenReturn(false);
when(mockDisplayRotation.isLandscapeOrSeascape(Surface.ROTATION_270)).thenReturn(true);
+ mMockDisplayRotation = mockDisplayRotation;
return mockDisplayRotation;
}
@@ -196,6 +201,24 @@ public class DisplayRotationImmersiveAppCompatPolicyTests extends WindowTestsBas
}
@Test
+ public void testDeferOrientationUpdate() {
+ assertFalse(mPolicy.deferOrientationUpdate());
+
+ doReturn(SCREEN_ORIENTATION_UNSPECIFIED).when(mMockDisplayRotation).getLastOrientation();
+ final WindowOrientationListener orientationListener = mock(WindowOrientationListener.class);
+ doReturn(Surface.ROTATION_90).when(orientationListener).getProposedRotation();
+ doReturn(orientationListener).when(mMockDisplayRotation).getOrientationListener();
+ spyOn(mDisplayContent.mTransitionController);
+ doReturn(true).when(mDisplayContent.mTransitionController)
+ .hasTransientLaunch(mDisplayContent);
+
+ assertTrue(mPolicy.deferOrientationUpdate());
+ mDisplayContent.mTransitionController.mStateValidators.getFirst().run();
+
+ verify(mWm).updateRotation(false, false);
+ }
+
+ @Test
public void testRotationChoiceEnforcedOnly_nullTopRunningActivity_lockNotEnforced() {
when(mDisplayContent.topRunningActivity()).thenReturn(null);
diff --git a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
index a0c5b54603f9..c016c5ead23c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/FrameRateSelectionPriorityTests.java
@@ -69,7 +69,9 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase {
private static final FrameRateVote FRAME_RATE_VOTE_60_PREFERRED =
new FrameRateVote(60, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT,
SurfaceControl.FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN);
-
+ private static final float HI_REFRESH_RATE = 90;
+ private static final float MID_REFRESH_RATE = 70;
+ private static final float LOW_REFRESH_RATE = 60;
WindowState createWindow(String name) {
WindowState window = createWindow(null, TYPE_APPLICATION, name);
when(window.mWmService.mDisplayManagerInternal.getRefreshRateSwitchingType())
@@ -82,14 +84,16 @@ public class FrameRateSelectionPriorityTests extends WindowTestsBase {
DisplayInfo di = new DisplayInfo(mDisplayInfo);
Mode defaultMode = di.getDefaultMode();
Mode hiMode = new Mode(1,
- defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 90);
+ defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), HI_REFRESH_RATE);
Mode midMode = new Mode(2,
- defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 70);
+ defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), MID_REFRESH_RATE);
Mode lowMode = new Mode(LOW_MODE_ID,
- defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), 60);
+ defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), LOW_REFRESH_RATE);
di.supportedModes = new Mode[] { hiMode, midMode };
di.appsSupportedModes = new Mode[] { hiMode, midMode, lowMode };
+ di.supportedRefreshRates = new float[] {HI_REFRESH_RATE, MID_REFRESH_RATE,
+ LOW_REFRESH_RATE};
di.defaultModeId = 1;
mRefreshRatePolicy = new RefreshRatePolicy(mWm, di, mDenylist);
when(mDisplayPolicy.getRefreshRatePolicy()).thenReturn(mRefreshRatePolicy);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 7ed8283efffd..aa992504f9a5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -434,6 +434,7 @@ public class RecentTasksTest extends WindowTestsBase {
@Test
public void testAddTaskCompatibleWindowingMode_withFreeformAndFullscreen_expectRemove() {
Task task1 = createTaskBuilder(".Task1")
+ .setTaskId(1)
.setFlags(FLAG_ACTIVITY_NEW_TASK)
.build();
doReturn(WINDOWING_MODE_FREEFORM).when(task1).getWindowingMode();
@@ -452,6 +453,10 @@ public class RecentTasksTest extends WindowTestsBase {
assertThat(mCallbacksRecorder.mTrimmed).isEmpty();
assertThat(mCallbacksRecorder.mRemoved).hasSize(1);
assertThat(mCallbacksRecorder.mRemoved).contains(task1);
+
+ TaskChangeNotificationController controller =
+ mAtm.getTaskChangeNotificationController();
+ verify(controller, times(1)).notifyRecentTaskRemovedForAddTask(task1.mTaskId);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index cc38f02ccc4c..73e5f58fa7e0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -101,6 +101,8 @@ public class RefreshRatePolicyTest extends WindowTestsBase {
defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), LOW_REFRESH_RATE);
mDisplayInfo.supportedModes = new Mode[] { hiMode, midMode };
mDisplayInfo.appsSupportedModes = new Mode[] { hiMode, midMode, lowMode };
+ mDisplayInfo.supportedRefreshRates = new float[] {HI_REFRESH_RATE, MID_REFRESH_RATE,
+ LOW_REFRESH_RATE};
mDisplayInfo.defaultModeId = HI_MODE_ID;
mPolicy = new RefreshRatePolicy(mWm, mDisplayInfo, mDenylist);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
index 791b5b59535a..a92fe3afbd78 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
@@ -162,6 +162,10 @@ public class SafeActivityOptionsTest {
verifySecureExceptionThrown(activityOptions, taskSupervisor);
activityOptions = ActivityOptions.makeBasic();
+ activityOptions.setTaskAlwaysOnTop(true);
+ verifySecureExceptionThrown(activityOptions, taskSupervisor);
+
+ activityOptions = ActivityOptions.makeBasic();
activityOptions.setLaunchDisplayId(DEFAULT_DISPLAY);
verifySecureExceptionThrown(activityOptions, taskSupervisor);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index ad6611827524..4fbe492ea7fb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -4928,6 +4928,7 @@ public class SizeCompatTests extends WindowTestsBase {
spyOn(pm);
final PackageManager.Property property = new PackageManager.Property("propertyName",
true /* value */, name.getPackageName(), name.getClassName());
+ // Activity level.
try {
doReturn(property).when(pm).getPropertyAsUser(
WindowManager.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY,
@@ -4938,6 +4939,19 @@ public class SizeCompatTests extends WindowTestsBase {
final ActivityRecord optOutActivity = new ActivityBuilder(mAtm)
.setComponent(name).setTask(mTask).build();
assertFalse(optOutActivity.isUniversalResizeable());
+
+ // Application level.
+ try {
+ doReturn(property).when(pm).getProperty(
+ WindowManager.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY,
+ name.getPackageName());
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ final ActivityRecord optOutAppActivity = new ActivityBuilder(mAtm)
+ .setComponent(getUniqueComponentName(mContext.getPackageName()))
+ .setTask(mTask).build();
+ assertFalse(optOutAppActivity.isUniversalResizeable());
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e22d75e4dfe3..ad5d42ad5a68 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -19599,4 +19599,37 @@ public class TelephonyManager {
throw ex.rethrowAsRuntimeException();
}
}
+
+ /**
+ * Returns carrier id maps to the passing CarrierIdentifier.
+ * To recognize a carrier (including MVNO) as a first-class identity,
+ * Android assigns each carrier with a canonical integer a.k.a. carrier id.
+ * The carrier ID is an Android platform-wide identifier for a carrier.
+ * AOSP maintains carrier ID assignments in
+ * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
+ *
+ * @param carrierIdentifier {@link CarrierIdentifier}
+ *
+ * @return Carrier id. Return {@link #UNKNOWN_CARRIER_ID} if the carrier cannot be identified.
+ * @throws UnsupportedOperationException If the device does not have
+ * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_CARRIER_ID_FROM_CARRIER_IDENTIFIER)
+ @SystemApi
+ @WorkerThread
+ @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public int getCarrierIdFromCarrierIdentifier(@NonNull CarrierIdentifier carrierIdentifier) {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.getCarrierIdFromIdentifier(carrierIdentifier);
+ }
+ } catch (RemoteException ex) {
+ // This could happen if binder process crashes.
+ }
+ return UNKNOWN_CARRIER_ID;
+ }
}
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 23203ed65e9a..bf103d52d0bf 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -746,7 +746,7 @@ public final class SatelliteManager {
* @hide
*/
public static final String ACTION_SATELLITE_SUBSCRIBER_ID_LIST_CHANGED =
- "android.telephony.action.ACTION_SATELLITE_SUBSCRIBER_ID_LIST_CHANGED";
+ "android.telephony.satellite.action.SATELLITE_SUBSCRIBER_ID_LIST_CHANGED";
/**
@@ -757,7 +757,7 @@ public final class SatelliteManager {
* @hide
*/
public static final String ACTION_SATELLITE_START_NON_EMERGENCY_SESSION =
- "android.telephony.action.ACTION_SATELLITE_START_NON_EMERGENCY_SESSION";
+ "android.telephony.satellite.action.SATELLITE_START_NON_EMERGENCY_SESSION";
/**
* Meta-data represents whether the application supports P2P SMS over carrier roaming satellite
* which needs manual trigger to connect to satellite. The messaging applications that supports
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d22e9fa20101..294c93c8e493 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -3519,4 +3519,15 @@ interface ITelephony {
* @hide
*/
void setNtnSmsSupported(boolean ntnSmsSupported);
+
+ /**
+ * Returns carrier id maps to the passing {@link CarrierIdentifier}.
+ *
+ * @param {@link CarrierIdentifier}.
+ *
+ * @return carrier id from passing {@link CarrierIdentifier} or {@link #UNKNOWN_CARRIER_ID}
+ * if the carrier cannot be identified
+ * @hide
+ */
+ int getCarrierIdFromIdentifier(in CarrierIdentifier carrierIdentifier);
}
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
index 64328275085d..e0900a64c52f 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/DesktopModeAppHelper.kt
@@ -23,6 +23,7 @@ import android.graphics.Rect
import android.graphics.Region
import android.os.SystemClock
import android.platform.uiautomatorhelpers.DeviceHelpers
+import android.tools.PlatformConsts
import android.tools.device.apphelpers.IStandardAppHelper
import android.tools.helpers.SYSTEMUI_PACKAGE
import android.tools.traces.parsers.WindowManagerStateHelper
@@ -163,7 +164,10 @@ open class DesktopModeAppHelper(private val innerHelper: IStandardAppHelper) :
.StateSyncBuilder()
.withAppTransitionIdle()
.apply {
- if (isPip) withPipShown() else withWindowSurfaceDisappeared(innerHelper)
+ if (isPip) withPipShown()
+ else
+ withWindowSurfaceDisappeared(innerHelper)
+ .withActivityState(innerHelper, PlatformConsts.STATE_STOPPED)
}
.waitForAndVerify()
}
diff --git a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
index 931e4f88aa8d..db4838ee6092 100644
--- a/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
+++ b/tests/FlickerTests/test-apps/app-helpers/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -250,18 +250,13 @@ open class PipAppHelper(instrumentation: Instrumentation) :
wmHelper,
launchedAppComponentMatcherOverride,
action,
- stringExtras,
- waitConditionsBuilder =
- wmHelper
- .StateSyncBuilder()
- .add(ConditionsFactory.isWMStateComplete())
- .withAppTransitionIdle()
- .add(ConditionsFactory.hasPipWindow())
+ stringExtras
)
wmHelper
.StateSyncBuilder()
.withWindowSurfaceAppeared(this)
+ .add(ConditionsFactory.isWMStateComplete())
.withPipShown()
.waitForAndVerify()
}
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index fe974e3da3be..af87bf724a30 100644
--- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
@@ -1014,7 +1014,7 @@ public class CrashRecoveryTest {
triggerFailureCount = 1;
}
for (int i = 0; i < triggerFailureCount; i++) {
- watchdog.onPackageFailure(packages, failureReason);
+ watchdog.notifyPackageFailure(packages, failureReason);
}
mTestLooper.dispatchAll();
if (Flags.recoverabilityDetection()) {
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index c25bed21a602..5a8a6bedf9eb 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -392,7 +392,7 @@ public class PackageWatchdogTest {
// Then fail APP_A below the threshold
for (int i = 0; i < watchdog.getTriggerFailureCount() - 1; i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
@@ -1025,14 +1025,14 @@ public class PackageWatchdogTest {
watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
// Fail APP_A below the threshold which should not trigger package failures
for (int i = 0; i < PackageWatchdog.DEFAULT_TRIGGER_FAILURE_COUNT - 1; i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
mTestLooper.dispatchAll();
assertThat(observer.mHealthCheckFailedPackages).isEmpty();
// One more to trigger the package failure
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
mTestLooper.dispatchAll();
assertThat(observer.mHealthCheckFailedPackages).containsExactly(APP_A);
@@ -1051,10 +1051,10 @@ public class PackageWatchdogTest {
TestObserver observer = new TestObserver(OBSERVER_NAME_1);
watchdog.startObservingHealth(observer, Arrays.asList(APP_A, APP_B), Long.MAX_VALUE);
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS + 1);
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
mTestLooper.dispatchAll();
@@ -1062,10 +1062,10 @@ public class PackageWatchdogTest {
// DEFAULT_TRIGGER_FAILURE_DURATION_MS.
assertThat(observer.mHealthCheckFailedPackages).isEmpty();
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS - 1);
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
mTestLooper.dispatchAll();
@@ -1129,17 +1129,17 @@ public class PackageWatchdogTest {
watchdog.startObservingHealth(observer, Arrays.asList(APP_A), Long.MAX_VALUE);
// Raise 2 failures at t=0 and t=900 respectively
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
moveTimeForwardAndDispatch(900);
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
// Raise 2 failures at t=1100
moveTimeForwardAndDispatch(200);
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
mTestLooper.dispatchAll();
@@ -1433,13 +1433,13 @@ public class PackageWatchdogTest {
TestObserver observer = new TestObserver(OBSERVER_NAME_1);
watchdog.startObservingHealth(observer, List.of(APP_A), SHORT_DURATION);
for (int i = 0; i < PackageWatchdog.DEFAULT_TRIGGER_FAILURE_COUNT - 1; i++) {
- watchdog.onPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
mTestLooper.dispatchAll();
assertThat(observer.mMitigatedPackages).isEmpty();
watchdog.startObservingHealth(observer, List.of(APP_A), LONG_DURATION);
- watchdog.onPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
+ watchdog.notifyPackageFailure(List.of(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
mTestLooper.dispatchAll();
assertThat(observer.mMitigatedPackages).isEqualTo(List.of(APP_A));
@@ -1737,7 +1737,7 @@ public class PackageWatchdogTest {
triggerFailureCount = 1;
}
for (int i = 0; i < triggerFailureCount; i++) {
- watchdog.onPackageFailure(packages, failureReason);
+ watchdog.notifyPackageFailure(packages, failureReason);
}
mTestLooper.dispatchAll();
if (Flags.recoverabilityDetection()) {
diff --git a/tools/aapt2/util/Util.h b/tools/aapt2/util/Util.h
index 40ff5b633d97..03da460affb5 100644
--- a/tools/aapt2/util/Util.h
+++ b/tools/aapt2/util/Util.h
@@ -111,8 +111,8 @@ const char* GetToolName();
// Retrieves the build fingerprint of aapt2.
std::string GetToolFingerprint();
-template <typename T>
-typename std::enable_if<std::is_arithmetic<T>::value, int>::type compare(const T& a, const T& b) {
+template <std::integral T>
+int compare(T a, T b) {
if (a < b) {
return -1;
} else if (a > b) {
@@ -123,10 +123,7 @@ typename std::enable_if<std::is_arithmetic<T>::value, int>::type compare(const T
// Makes a std::unique_ptr<> with the template parameter inferred by the compiler.
// This will be present in C++14 and can be removed then.
-template <typename T, class... Args>
-std::unique_ptr<T> make_unique(Args&&... args) {
- return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
-}
+using std::make_unique;
// Writes a set of items to the std::ostream, joining the times with the provided separator.
template <typename Container>
diff --git a/tools/systemfeatures/Android.bp b/tools/systemfeatures/Android.bp
index e6d0a3d4149f..2ebede39504e 100644
--- a/tools/systemfeatures/Android.bp
+++ b/tools/systemfeatures/Android.bp
@@ -13,6 +13,7 @@ java_library_host {
srcs: [
"src/**/*.java",
"src/**/*.kt",
+ ":framework-metalava-annotations",
],
static_libs: [
"guava",
@@ -26,6 +27,12 @@ java_binary_host {
static_libs: ["systemfeatures-gen-lib"],
}
+java_plugin {
+ name: "systemfeatures-metadata-processor",
+ processor_class: "com.android.systemfeatures.SystemFeaturesMetadataProcessor",
+ static_libs: ["systemfeatures-gen-lib"],
+}
+
genrule {
name: "systemfeatures-gen-tests-srcs",
cmd: "$(location systemfeatures-gen-tool) com.android.systemfeatures.RwNoFeatures --readonly=false > $(location RwNoFeatures.java) && " +
@@ -61,6 +68,7 @@ java_test_host {
"systemfeatures-gen-lib",
"truth",
],
+ plugins: ["systemfeatures-metadata-processor"],
}
// Rename the goldens as they may be copied into the source tree, and we don't
diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
new file mode 100644
index 000000000000..100d869a663f
--- /dev/null
+++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
@@ -0,0 +1,110 @@
+/*
+ * 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.systemfeatures
+
+import android.annotation.SdkConstant
+import com.squareup.javapoet.FieldSpec
+import com.squareup.javapoet.JavaFile
+import com.squareup.javapoet.TypeSpec
+import java.io.IOException
+import javax.annotation.processing.AbstractProcessor
+import javax.annotation.processing.ProcessingEnvironment
+import javax.annotation.processing.RoundEnvironment
+import javax.lang.model.SourceVersion
+import javax.lang.model.element.Modifier
+import javax.lang.model.element.TypeElement
+import javax.tools.Diagnostic
+
+/*
+ * Simple Java code generator for computing metadata for system features.
+ *
+ * <p>The output is a single class file, `com.android.internal.pm.SystemFeaturesMetadata`, with
+ * properties computed from feature constant definitions in the PackageManager class. This
+ * class is only produced if the processed environment includes PackageManager; all other
+ * invocations are ignored.
+ */
+class SystemFeaturesMetadataProcessor : AbstractProcessor() {
+
+ private lateinit var packageManagerType: TypeElement
+
+ override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latestSupported()
+
+ override fun getSupportedAnnotationTypes() = setOf(SDK_CONSTANT_ANNOTATION_NAME)
+
+ override fun init(processingEnv: ProcessingEnvironment) {
+ super.init(processingEnv)
+ packageManagerType =
+ processingEnv.elementUtils.getTypeElement("android.content.pm.PackageManager")!!
+ }
+
+ override fun process(annotations: Set<TypeElement>, roundEnv: RoundEnvironment): Boolean {
+ if (roundEnv.processingOver()) {
+ return false
+ }
+
+ // We're only interested in feature constants defined in PackageManager.
+ var featureCount = 0
+ roundEnv.getElementsAnnotatedWith(SdkConstant::class.java).forEach {
+ if (
+ it.enclosingElement == packageManagerType &&
+ it.getAnnotation(SdkConstant::class.java).value ==
+ SdkConstant.SdkConstantType.FEATURE
+ ) {
+ featureCount++
+ }
+ }
+
+ if (featureCount == 0) {
+ // This is fine, and happens for any environment that doesn't include PackageManager.
+ return false
+ }
+
+ val systemFeatureMetadata =
+ TypeSpec.classBuilder("SystemFeaturesMetadata")
+ .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
+ .addJavadoc("@hide")
+ .addField(
+ FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
+ .addJavadoc(
+ "The number of `@SdkConstant` features defined in PackageManager."
+ )
+ .addJavadoc("@hide")
+ .initializer("\$L", featureCount)
+ .build()
+ )
+ .build()
+
+ try {
+ JavaFile.builder("com.android.internal.pm", systemFeatureMetadata)
+ .skipJavaLangImports(true)
+ .build()
+ .writeTo(processingEnv.filer)
+ } catch (e: IOException) {
+ processingEnv.messager.printMessage(
+ Diagnostic.Kind.ERROR,
+ "Failed to write file: ${e.message}",
+ )
+ }
+
+ return true
+ }
+
+ companion object {
+ private val SDK_CONSTANT_ANNOTATION_NAME = SdkConstant::class.qualifiedName
+ }
+}
diff --git a/tools/systemfeatures/tests/src/PackageManager.java b/tools/systemfeatures/tests/src/PackageManager.java
index db670482065a..839a9377476d 100644
--- a/tools/systemfeatures/tests/src/PackageManager.java
+++ b/tools/systemfeatures/tests/src/PackageManager.java
@@ -16,14 +16,33 @@
package android.content.pm;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+
/** Stub for testing */
public class PackageManager {
+ @SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_AUTO = "automotive";
+
+ @SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_PC = "pc";
+
+ @SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_VULKAN = "vulkan";
+
+ @SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_WATCH = "watch";
+
+ @SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_WIFI = "wifi";
+ @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+ public static final String FEATURE_INTENT_CATEGORY = "intent_category_with_feature_name_prefix";
+
+ public static final String FEATURE_NOT_ANNOTATED = "not_annotated";
+
+ public static final String NOT_FEATURE = "not_feature";
+
/** @hide */
public boolean hasSystemFeature(String featureName, int version) {
return false;
diff --git a/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
new file mode 100644
index 000000000000..4ffb5b979d75
--- /dev/null
+++ b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemfeatures;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.internal.pm.SystemFeaturesMetadata;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class SystemFeaturesMetadataProcessorTest {
+
+ @Test
+ public void testSdkFeatureCount() {
+ // See the fake PackageManager definition in this directory.
+ // It defines 5 annotated features, and any/all other constants should be ignored.
+ assertThat(SystemFeaturesMetadata.SDK_FEATURE_COUNT).isEqualTo(5);
+ }
+}