summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PREUPLOAD.cfg1
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java11
-rw-r--r--apex/media/aidl/private/android/media/IMediaCommunicationService.aidl21
-rw-r--r--apex/media/framework/Android.bp3
-rw-r--r--apex/media/framework/api/current.txt3
-rw-r--r--apex/media/framework/jarjar_rules.txt1
-rw-r--r--apex/media/framework/java/android/media/MediaCommunicationManager.java49
-rw-r--r--apex/media/framework/java/android/media/MediaFrameworkInitializer.java10
-rw-r--r--apex/media/service/Android.bp41
-rw-r--r--apex/media/service/api/current.txt1
-rw-r--r--apex/media/service/api/removed.txt1
-rw-r--r--apex/media/service/api/system-server-current.txt1
-rw-r--r--apex/media/service/api/system-server-removed.txt1
-rw-r--r--apex/media/service/java/com/android/server/media/MediaCommunicationService.java41
-rw-r--r--core/api/current.txt27
-rw-r--r--core/api/module-lib-current.txt5
-rw-r--r--core/api/system-current.txt200
-rw-r--r--core/api/system-lint-baseline.txt17
-rw-r--r--core/api/test-current.txt3
-rw-r--r--core/java/android/app/ActivityThread.java5
-rw-r--r--core/java/android/app/ApplicationExitInfo.java2
-rw-r--r--core/java/android/app/ApplicationPackageManager.java22
-rw-r--r--core/java/android/app/PendingIntent.java2
-rw-r--r--core/java/android/app/SystemServiceRegistry.java73
-rw-r--r--core/java/android/app/TaskInfo.java20
-rw-r--r--core/java/android/app/assist/AssistStructure.java2
-rw-r--r--core/java/android/app/search/Query.java3
-rw-r--r--core/java/android/app/search/SearchAction.java5
-rw-r--r--core/java/android/app/search/SearchContext.java4
-rw-r--r--core/java/android/app/search/SearchTarget.java4
-rw-r--r--core/java/android/app/smartspace/ISmartspaceCallback.aidl27
-rw-r--r--core/java/android/app/smartspace/ISmartspaceManager.aidl45
-rw-r--r--core/java/android/app/smartspace/SmartspaceAction.java353
-rw-r--r--core/java/android/app/smartspace/SmartspaceConfig.aidl19
-rw-r--r--core/java/android/app/smartspace/SmartspaceConfig.java202
-rw-r--r--core/java/android/app/smartspace/SmartspaceManager.java64
-rw-r--r--core/java/android/app/smartspace/SmartspaceSession.java284
-rw-r--r--core/java/android/app/smartspace/SmartspaceSessionId.aidl19
-rw-r--r--core/java/android/app/smartspace/SmartspaceSessionId.java114
-rw-r--r--core/java/android/app/smartspace/SmartspaceTarget.aidl19
-rw-r--r--core/java/android/app/smartspace/SmartspaceTarget.java660
-rw-r--r--core/java/android/app/smartspace/SmartspaceTargetEvent.aidl19
-rw-r--r--core/java/android/app/smartspace/SmartspaceTargetEvent.java204
-rw-r--r--core/java/android/appwidget/AppWidgetProviderInfo.java8
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java2
-rw-r--r--core/java/android/content/Context.java23
-rw-r--r--core/java/android/content/pm/LauncherActivityInfo.java27
-rw-r--r--core/java/android/content/pm/PackageInfo.java2
-rw-r--r--core/java/android/content/pm/PackageManager.java17
-rw-r--r--core/java/android/content/pm/Signature.java4
-rw-r--r--core/java/android/hardware/Battery.java74
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl4
-rw-r--r--core/java/android/hardware/input/InputDeviceBattery.java65
-rw-r--r--core/java/android/hardware/input/InputManager.java58
-rw-r--r--core/java/android/hardware/location/ContextHubClientCallback.java31
-rw-r--r--core/java/android/hardware/location/ContextHubIntentEvent.java45
-rw-r--r--core/java/android/hardware/location/ContextHubManager.java128
-rw-r--r--core/java/android/hardware/location/IContextHubClientCallback.aidl3
-rw-r--r--core/java/android/hardware/location/IContextHubService.aidl6
-rw-r--r--core/java/android/hardware/location/NanoAppState.java24
-rw-r--r--core/java/android/hardware/usb/UsbManager.java9
-rw-r--r--core/java/android/net/IpSecManager.java91
-rw-r--r--core/java/android/net/NetworkState.java19
-rw-r--r--core/java/android/os/PowerManager.java80
-rw-r--r--core/java/android/provider/DeviceConfig.java8
-rw-r--r--core/java/android/provider/Settings.java23
-rw-r--r--core/java/android/service/autofill/Dataset.java4
-rw-r--r--core/java/android/service/dataloader/OWNERS1
-rw-r--r--core/java/android/service/notification/INotificationListener.aidl2
-rw-r--r--core/java/android/service/notification/NotificationAssistantService.java25
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java3
-rw-r--r--core/java/android/service/smartspace/ISmartspaceService.aidl46
-rw-r--r--core/java/android/service/smartspace/SmartspaceService.java313
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java3
-rw-r--r--core/java/android/util/imetracing/ImeTracing.java6
-rw-r--r--core/java/android/util/imetracing/OWNERS3
-rw-r--r--core/java/android/view/ContentInfo.java4
-rw-r--r--core/java/android/view/InputDevice.java35
-rw-r--r--core/java/android/view/InsetsFlags.java12
-rw-r--r--core/java/android/view/InsetsState.java33
-rw-r--r--core/java/android/view/SurfaceControl.java35
-rw-r--r--core/java/android/view/View.java14
-rw-r--r--core/java/android/view/ViewStructure.java4
-rw-r--r--core/java/android/view/WindowInsetsController.java15
-rw-r--r--core/java/android/view/WindowManager.java17
-rw-r--r--core/java/android/view/inputmethod/InputConnection.java2
-rw-r--r--core/java/android/view/textservice/TextServicesManager.java4
-rw-r--r--core/java/android/widget/SpellChecker.java58
-rw-r--r--core/java/android/window/TaskOrganizer.java3
-rw-r--r--core/java/com/android/internal/app/OWNERS1
-rw-r--r--core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java5
-rw-r--r--core/java/com/android/internal/os/BatteryUsageStatsProvider.java11
-rw-r--r--core/java/com/android/internal/policy/AttributeCache.java (renamed from services/core/java/com/android/server/AttributeCache.java)56
-rw-r--r--core/java/com/android/internal/policy/ClipRectLRAnimation.java (renamed from services/core/java/com/android/server/wm/animation/ClipRectLRAnimation.java)4
-rw-r--r--core/java/com/android/internal/policy/ClipRectTBAnimation.java (renamed from services/core/java/com/android/server/wm/animation/ClipRectTBAnimation.java)5
-rw-r--r--core/java/com/android/internal/policy/LogDecelerateInterpolator.java (renamed from services/core/java/com/android/server/policy/LogDecelerateInterpolator.java)5
-rw-r--r--core/java/com/android/internal/policy/TransitionAnimation.java960
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl7
-rw-r--r--core/jni/android_view_InputDevice.cpp10
-rw-r--r--core/jni/android_view_SurfaceControl.cpp20
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp16
-rw-r--r--core/res/AndroidManifest.xml5
-rw-r--r--core/res/res/values/config.xml9
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/coretests/AndroidManifest.xml5
-rw-r--r--core/tests/coretests/src/android/app/activity/BroadcastTest.java39
-rw-r--r--core/tests/coretests/src/android/app/activity/LaunchpadActivity.java40
-rw-r--r--core/tests/coretests/src/android/app/activity/LocalDeniedReceiver.java2
-rw-r--r--core/tests/coretests/src/android/app/activity/RemoteDeniedReceiver.java2
-rw-r--r--core/tests/coretests/src/android/content/pm/SignatureTest.java26
-rw-r--r--core/tests/coretests/src/android/hardware/input/InputDeviceSensorManagerTest.java2
-rw-r--r--core/tests/overlaytests/device/AndroidTest.xml8
-rw-r--r--graphics/java/android/graphics/RenderNode.java33
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java5
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java313
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java27
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java16
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java32
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java21
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java5
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt16
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt16
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt14
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt13
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottomTest.kt18
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncherTest.kt11
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreenTest.kt12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt12
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt13
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt11
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToHomeTest.kt11
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java37
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java5
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java12
-rw-r--r--libs/hwui/Android.bp1
-rw-r--r--libs/hwui/RenderProperties.h6
-rw-r--r--libs/hwui/effects/StretchEffect.cpp27
-rw-r--r--libs/hwui/effects/StretchEffect.h66
-rw-r--r--libs/hwui/jni/android_graphics_RenderNode.cpp27
-rw-r--r--libs/hwui/pipeline/skia/RenderNodeDrawable.cpp20
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp8
-rw-r--r--location/java/android/location/GnssMeasurement.java6
-rw-r--r--location/java/android/location/LocationManager.java1
-rw-r--r--location/java/android/location/provider/LocationProviderBase.java4
-rw-r--r--media/java/android/media/MediaServiceManager.java9
-rw-r--r--media/java/android/media/musicrecognition/MusicRecognitionManager.java5
-rw-r--r--media/java/android/media/musicrecognition/MusicRecognitionService.java5
-rw-r--r--media/java/android/media/tv/tuner/Tuner.java2
-rw-r--r--media/java/android/media/tv/tuner/filter/Filter.java16
-rw-r--r--media/java/android/media/tv/tuner/filter/RestartEvent.java24
-rw-r--r--media/jni/android_media_MediaMetricsJNI.cpp8
-rw-r--r--packages/Connectivity/framework/src/android/net/CaptivePortal.java (renamed from core/java/android/net/CaptivePortal.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/CaptivePortalData.aidl (renamed from core/java/android/net/CaptivePortalData.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/CaptivePortalData.java (renamed from core/java/android/net/CaptivePortalData.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectionInfo.aidl (renamed from core/java/android/net/ConnectionInfo.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectionInfo.java (renamed from core/java/android/net/ConnectionInfo.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.aidl (renamed from core/java/android/net/ConnectivityDiagnosticsManager.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.java (renamed from core/java/android/net/ConnectivityDiagnosticsManager.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java83
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectivityManager.java (renamed from core/java/android/net/ConnectivityManager.java)22
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectivityMetricsEvent.aidl (renamed from core/java/android/net/ConnectivityMetricsEvent.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectivityThread.java (renamed from core/java/android/net/ConnectivityThread.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/DhcpInfo.aidl (renamed from core/java/android/net/DhcpInfo.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/DhcpInfo.java (renamed from core/java/android/net/DhcpInfo.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/DnsResolver.java (renamed from core/java/android/net/DnsResolver.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ICaptivePortal.aidl (renamed from core/java/android/net/ICaptivePortal.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/IConnectivityDiagnosticsCallback.aidl (renamed from core/java/android/net/IConnectivityDiagnosticsCallback.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl (renamed from core/java/android/net/IConnectivityManager.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ISocketKeepaliveCallback.aidl (renamed from core/java/android/net/ISocketKeepaliveCallback.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ITestNetworkManager.aidl (renamed from core/java/android/net/ITestNetworkManager.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/InetAddresses.java (renamed from core/java/android/net/InetAddresses.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/InterfaceConfiguration.aidl (renamed from core/java/android/net/InterfaceConfiguration.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/InvalidPacketException.java (renamed from core/java/android/net/InvalidPacketException.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/IpConfiguration.aidl (renamed from core/java/android/net/IpConfiguration.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/IpConfiguration.java (renamed from core/java/android/net/IpConfiguration.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/IpPrefix.aidl (renamed from core/java/android/net/IpPrefix.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/IpPrefix.java (renamed from core/java/android/net/IpPrefix.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/KeepalivePacketData.aidl (renamed from core/java/android/net/KeepalivePacketData.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/KeepalivePacketData.java (renamed from core/java/android/net/KeepalivePacketData.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/LinkAddress.aidl (renamed from core/java/android/net/LinkAddress.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/LinkAddress.java (renamed from core/java/android/net/LinkAddress.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/LinkProperties.aidl (renamed from core/java/android/net/LinkProperties.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/LinkProperties.java (renamed from core/java/android/net/LinkProperties.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/MacAddress.aidl (renamed from core/java/android/net/MacAddress.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/MacAddress.java (renamed from core/java/android/net/MacAddress.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NattKeepalivePacketData.java (renamed from core/java/android/net/NattKeepalivePacketData.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NattSocketKeepalive.java (renamed from core/java/android/net/NattSocketKeepalive.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/Network.aidl (renamed from core/java/android/net/Network.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/Network.java (renamed from core/java/android/net/Network.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkAgent.java (renamed from core/java/android/net/NetworkAgent.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkAgentConfig.aidl (renamed from core/java/android/net/NetworkAgentConfig.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java (renamed from core/java/android/net/NetworkAgentConfig.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkCapabilities.aidl (renamed from core/java/android/net/NetworkCapabilities.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkCapabilities.java (renamed from core/java/android/net/NetworkCapabilities.java)8
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkConfig.java (renamed from core/java/android/net/NetworkConfig.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkInfo.aidl (renamed from core/java/android/net/NetworkInfo.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkInfo.java (renamed from core/java/android/net/NetworkInfo.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkProvider.java (renamed from core/java/android/net/NetworkProvider.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkRequest.aidl (renamed from core/java/android/net/NetworkRequest.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkRequest.java (renamed from core/java/android/net/NetworkRequest.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkUtils.java (renamed from core/java/android/net/NetworkUtils.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/PacProxySelector.java (renamed from core/java/android/net/PacProxySelector.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/Proxy.java (renamed from core/java/android/net/Proxy.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ProxyInfo.aidl (renamed from core/java/android/net/ProxyInfo.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/ProxyInfo.java (renamed from core/java/android/net/ProxyInfo.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/RouteInfo.aidl (renamed from core/java/android/net/RouteInfo.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/RouteInfo.java (renamed from core/java/android/net/RouteInfo.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/SocketKeepalive.java (renamed from core/java/android/net/SocketKeepalive.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/StaticIpConfiguration.aidl (renamed from core/java/android/net/StaticIpConfiguration.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/StaticIpConfiguration.java (renamed from core/java/android/net/StaticIpConfiguration.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java (renamed from core/java/android/net/TcpKeepalivePacketData.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/TcpRepairWindow.java (renamed from core/java/android/net/TcpRepairWindow.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/TcpSocketKeepalive.java (renamed from core/java/android/net/TcpSocketKeepalive.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/TestNetworkInterface.aidl (renamed from core/java/android/net/TestNetworkInterface.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/TestNetworkInterface.java (renamed from core/java/android/net/TestNetworkInterface.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/TestNetworkManager.java (renamed from core/java/android/net/TestNetworkManager.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/TransportInfo.java (renamed from core/java/android/net/TransportInfo.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/UidRange.aidl (renamed from core/java/android/net/UidRange.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/VpnManager.java (renamed from core/java/android/net/VpnManager.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/VpnService.java (renamed from core/java/android/net/VpnService.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.aidl (renamed from core/java/android/net/apf/ApfCapabilities.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.java (renamed from core/java/android/net/apf/ApfCapabilities.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/util/DnsUtils.java (renamed from core/java/android/net/util/DnsUtils.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/util/KeepaliveUtils.java (renamed from core/java/android/net/util/KeepaliveUtils.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java (renamed from core/java/android/net/util/MultinetworkPolicyTracker.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/util/SocketUtils.java (renamed from core/java/android/net/util/SocketUtils.java)0
-rw-r--r--packages/Connectivity/service/Android.bp1
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml18
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml18
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/drawable/track_off.xml2
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml12
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/drawable/track_on.xml2
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml13
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml4
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml1
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values/colors.xml1
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml6
-rw-r--r--packages/SettingsLib/MainSwitchPreference/res/values/styles.xml1
-rw-r--r--packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java6
-rw-r--r--packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java28
-rw-r--r--packages/SettingsLib/UsageProgressBarPreference/Android.bp1
-rw-r--r--packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml34
-rw-r--r--packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java22
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java27
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java30
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java2
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml4
-rw-r--r--packages/SystemUI/res/drawable/privacy_item_circle_camera.xml8
-rw-r--r--packages/SystemUI/res/drawable/privacy_item_circle_location.xml8
-rw-r--r--packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml8
-rw-r--r--packages/SystemUI/res/layout/privacy_dialog.xml10
-rw-r--r--packages/SystemUI/res/layout/privacy_dialog_item.xml41
-rw-r--r--packages/SystemUI/res/values-af/strings.xml14
-rw-r--r--packages/SystemUI/res/values-am/strings.xml5
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml14
-rw-r--r--packages/SystemUI/res/values-as/strings.xml5
-rw-r--r--packages/SystemUI/res/values-az/strings.xml14
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-be/strings.xml14
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml14
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml5
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml14
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml14
-rw-r--r--packages/SystemUI/res/values-da/strings.xml16
-rw-r--r--packages/SystemUI/res/values-de/strings.xml19
-rw-r--r--packages/SystemUI/res/values-el/strings.xml14
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml5
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml5
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml5
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml5
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml5
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml5
-rw-r--r--packages/SystemUI/res/values-es/strings.xml14
-rw-r--r--packages/SystemUI/res/values-et/strings.xml14
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml14
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml5
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml14
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml5
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml14
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml14
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml14
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml14
-rw-r--r--packages/SystemUI/res/values-in/strings.xml14
-rw-r--r--packages/SystemUI/res/values-is/strings.xml14
-rw-r--r--packages/SystemUI/res/values-it/strings.xml14
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml19
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml14
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml26
-rw-r--r--packages/SystemUI/res/values-km/strings.xml14
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml14
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml14
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml14
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml14
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml19
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml14
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml25
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml14
-rw-r--r--packages/SystemUI/res/values-my/strings.xml14
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml14
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-or/strings.xml14
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml25
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml5
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml5
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml5
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml14
-rw-r--r--packages/SystemUI/res/values-si/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml14
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml14
-rw-r--r--packages/SystemUI/res/values-te/strings.xml19
-rw-r--r--packages/SystemUI/res/values-th/strings.xml14
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml14
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml14
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml14
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml14
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml16
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml14
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml14
-rw-r--r--packages/SystemUI/res/values/dimens.xml6
-rw-r--r--packages/SystemUI/res/values/flags.xml5
-rw-r--r--packages/SystemUI/res/values/strings.xml4
-rw-r--r--packages/SystemUI/res/values/styles.xml5
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIApplication.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java227
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java263
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java106
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java528
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java212
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/SyncExecutor.java48
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java5
-rw-r--r--proto/src/system_messages.proto4
-rw-r--r--services/Android.bp3
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java90
-rw-r--r--services/core/java/com/android/server/PackageWatchdog.java19
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java19
-rw-r--r--services/core/java/com/android/server/TestNetworkService.java6
-rw-r--r--services/core/java/com/android/server/Watchdog.java1
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java25
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java18
-rw-r--r--services/core/java/com/android/server/am/CachedAppOptimizer.java10
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java2
-rw-r--r--services/core/java/com/android/server/am/ProcessProfileRecord.java2
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java2
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java3
-rw-r--r--services/core/java/com/android/server/graphics/fonts/FontCrashDetector.java92
-rw-r--r--services/core/java/com/android/server/graphics/fonts/FontManagerService.java53
-rw-r--r--services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java4
-rw-r--r--services/core/java/com/android/server/input/InputManagerService.java17
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java142
-rw-r--r--services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java10
-rw-r--r--services/core/java/com/android/server/location/contexthub/ContextHubService.java13
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java47
-rw-r--r--services/core/java/com/android/server/notification/ValidateNotificationPeople.java47
-rw-r--r--services/core/java/com/android/server/pm/BackgroundDexOptService.java4
-rw-r--r--services/core/java/com/android/server/pm/DynamicCodeLoggingService.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java30
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceUtils.java9
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java30
-rw-r--r--services/core/java/com/android/server/rollback/Rollback.java1
-rw-r--r--services/core/java/com/android/server/vcn/Vcn.java13
-rw-r--r--services/core/java/com/android/server/vcn/VcnGatewayConnection.java12
-rw-r--r--services/core/java/com/android/server/vcn/VcnNetworkProvider.java20
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java18
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java8
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java743
-rw-r--r--services/core/java/com/android/server/wm/BackgroundActivityStartCallback.java6
-rw-r--r--services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java264
-rw-r--r--services/core/java/com/android/server/wm/BarController.java61
-rw-r--r--services/core/java/com/android/server/wm/DisplayArea.java17
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java49
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java141
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java14
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java42
-rw-r--r--services/core/java/com/android/server/wm/Task.java28
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java193
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java16
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp25
-rw-r--r--services/java/com/android/server/SystemServer.java16
-rw-r--r--services/people/java/com/android/server/people/data/DataManager.java7
-rw-r--r--services/smartspace/Android.bp13
-rw-r--r--services/smartspace/java/com/android/server/smartspace/RemoteSmartspaceService.java112
-rw-r--r--services/smartspace/java/com/android/server/smartspace/SmartspaceManagerService.java184
-rw-r--r--services/smartspace/java/com/android/server/smartspace/SmartspaceManagerServiceShellCommand.java84
-rw-r--r--services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java411
-rw-r--r--services/tests/servicestests/src/com/android/server/VibratorServiceTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/graphics/fonts/FontCrashDetectorTest.java77
-rw-r--r--services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java115
-rw-r--r--services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java29
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java80
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java15
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java51
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java55
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java50
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java2
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java62
-rw-r--r--telephony/java/android/telephony/ims/ImsCallProfile.java4
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl15
-rw-r--r--tests/FlickerTests/TEST_MAPPING13
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt11
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt11
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt11
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt14
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt11
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt11
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt11
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt12
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt11
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt13
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt11
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt13
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt20
-rw-r--r--tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java44
-rw-r--r--tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java40
-rw-r--r--tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java18
-rw-r--r--tests/UsbTests/src/com/android/server/usb/UsbManagerNoPermTest.java37
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java57
-rw-r--r--wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java6
481 files changed, 10056 insertions, 3598 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index cdf5df6c6bd3..30ed7de92614 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -8,6 +8,7 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
cmds/input/
cmds/uinput/
core/jni/
+ libs/hwui/
libs/input/
native/
services/core/jni/
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index e05f0b062dbe..223f3b04d4e6 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -665,9 +665,18 @@ class JobConcurrencyManager {
WorkTypeConfig(@NonNull String configIdentifier, int defaultMaxTotal,
List<Pair<Integer, Integer>> defaultMin, List<Pair<Integer, Integer>> defaultMax) {
mConfigIdentifier = configIdentifier;
- mDefaultMaxTotal = mMaxTotal = defaultMaxTotal;
+ mDefaultMaxTotal = mMaxTotal = Math.min(defaultMaxTotal, MAX_JOB_CONTEXTS_COUNT);
+ int numReserved = 0;
for (int i = defaultMin.size() - 1; i >= 0; --i) {
mDefaultMinReservedSlots.put(defaultMin.get(i).first, defaultMin.get(i).second);
+ numReserved += defaultMin.get(i).second;
+ }
+ if (mDefaultMaxTotal < 0 || numReserved > mDefaultMaxTotal) {
+ // We only create new configs on boot, so this should trigger during development
+ // (before the code gets checked in), so this makes sure the hard-coded defaults
+ // make sense. DeviceConfig values will be handled gracefully in update().
+ throw new IllegalArgumentException("Invalid default config: t=" + defaultMaxTotal
+ + " min=" + defaultMin + " max=" + defaultMax);
}
for (int i = defaultMax.size() - 1; i >= 0; --i) {
mDefaultMaxAllowedSlots.put(defaultMax.get(i).first, defaultMax.get(i).second);
diff --git a/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl b/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl
new file mode 100644
index 000000000000..3d50d14e1b83
--- /dev/null
+++ b/apex/media/aidl/private/android/media/IMediaCommunicationService.aidl
@@ -0,0 +1,21 @@
+/**
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media;
+
+/** {@hide} */
+interface IMediaCommunicationService {
+}
+
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp
index 60dea079a36b..5773e4de3f4e 100644
--- a/apex/media/framework/Android.bp
+++ b/apex/media/framework/Android.bp
@@ -38,6 +38,7 @@ java_library {
static_libs: [
"exoplayer2-extractor",
"mediatranscoding_aidl_interface-java",
+ "modules-utils-build",
],
jarjar_rules: "jarjar_rules.txt",
@@ -52,6 +53,7 @@ java_library {
visibility: [
"//frameworks/av/apex:__subpackages__",
"//frameworks/base", // For framework-all
+ "//frameworks/base/apex/media/service",
],
}
@@ -80,6 +82,7 @@ filegroup {
"java/android/media/Session2CommandGroup.java",
"java/android/media/Session2Link.java",
"java/android/media/Session2Token.java",
+ "java/android/media/MediaCommunicationManager.java",
],
path: "java",
}
diff --git a/apex/media/framework/api/current.txt b/apex/media/framework/api/current.txt
index 2543a9cad576..8b9990f9e833 100644
--- a/apex/media/framework/api/current.txt
+++ b/apex/media/framework/api/current.txt
@@ -28,6 +28,9 @@ package android.media {
ctor public ApplicationMediaCapabilities.FormatNotFoundException(@NonNull String);
}
+ public class MediaCommunicationManager {
+ }
+
public class MediaController2 implements java.lang.AutoCloseable {
method public void cancelSessionCommand(@NonNull Object);
method public void close();
diff --git a/apex/media/framework/jarjar_rules.txt b/apex/media/framework/jarjar_rules.txt
index d89d9d3343d1..eb71fddc05cb 100644
--- a/apex/media/framework/jarjar_rules.txt
+++ b/apex/media/framework/jarjar_rules.txt
@@ -1 +1,2 @@
+rule com.android.modules.utils.** android.media.internal.utils.@1
rule com.google.android.exoplayer2.** android.media.internal.exo.@1
diff --git a/apex/media/framework/java/android/media/MediaCommunicationManager.java b/apex/media/framework/java/android/media/MediaCommunicationManager.java
new file mode 100644
index 000000000000..b8065ef8c597
--- /dev/null
+++ b/apex/media/framework/java/android/media/MediaCommunicationManager.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media;
+
+import android.annotation.NonNull;
+import android.annotation.SystemService;
+import android.content.Context;
+
+import com.android.modules.utils.build.SdkLevel;
+
+/**
+ * Provides support for interacting with {@link android.media.MediaSession2 MediaSession2s}
+ * that applications have published to express their ongoing media playback state.
+ */
+// TODO: Add notifySession2Created() and sendMessage().
+@SystemService(Context.MEDIA_COMMUNICATION_SERVICE)
+public class MediaCommunicationManager {
+ private static final String TAG = "MediaCommunicationManager";
+
+ private final Context mContext;
+ private final IMediaCommunicationService mService;
+
+ /**
+ * @hide
+ */
+ public MediaCommunicationManager(@NonNull Context context) {
+ if (!SdkLevel.isAtLeastS()) {
+ throw new UnsupportedOperationException("Android version must be S or greater.");
+ }
+ mContext = context;
+ mService = IMediaCommunicationService.Stub.asInterface(
+ MediaFrameworkInitializer.getMediaServiceManager()
+ .getMediaCommunicationServiceRegisterer()
+ .get());
+ }
+}
diff --git a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java b/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
index 813ad7b43932..93328355026e 100644
--- a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
+++ b/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
@@ -19,10 +19,11 @@ package android.media;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.SystemApi.Client;
-import android.media.MediaTranscodeManager;
import android.app.SystemServiceRegistry;
import android.content.Context;
+import com.android.modules.utils.build.SdkLevel;
+
/**
* Class for performing registration for all media services on com.android.media apex.
*
@@ -74,5 +75,12 @@ public class MediaFrameworkInitializer {
MediaTranscodeManager.class,
context -> new MediaTranscodeManager(context)
);
+ if (SdkLevel.isAtLeastS()) {
+ SystemServiceRegistry.registerContextAwareService(
+ Context.MEDIA_COMMUNICATION_SERVICE,
+ MediaCommunicationManager.class,
+ context -> new MediaCommunicationManager(context)
+ );
+ }
}
}
diff --git a/apex/media/service/Android.bp b/apex/media/service/Android.bp
new file mode 100644
index 000000000000..5b24cfa4219b
--- /dev/null
+++ b/apex/media/service/Android.bp
@@ -0,0 +1,41 @@
+// Copyright 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+filegroup {
+ name: "service-media-s-sources",
+ srcs: [
+ "java/**/*.java",
+ ],
+ path: "java",
+ visibility: ["//frameworks/base/services"], // TODO(b/177640454): Should be private.
+}
+
+java_sdk_library {
+ name: "service-media-s",
+ permitted_packages: [
+ "com.android.server.media",
+ ],
+ defaults: ["framework-system-server-module-defaults"],
+ srcs: [
+ ":service-media-s-sources",
+ ],
+ libs: [
+ "updatable-media",
+ ],
+ sdk_version: "system_server_current",
+ min_sdk_version: "29", // TODO: We may need to bump this at some point.
+ apex_available: [
+ "com.android.media",
+ ],
+}
+
diff --git a/apex/media/service/api/current.txt b/apex/media/service/api/current.txt
new file mode 100644
index 000000000000..d802177e249b
--- /dev/null
+++ b/apex/media/service/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/service/api/removed.txt b/apex/media/service/api/removed.txt
new file mode 100644
index 000000000000..d802177e249b
--- /dev/null
+++ b/apex/media/service/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/service/api/system-server-current.txt b/apex/media/service/api/system-server-current.txt
new file mode 100644
index 000000000000..d802177e249b
--- /dev/null
+++ b/apex/media/service/api/system-server-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/service/api/system-server-removed.txt b/apex/media/service/api/system-server-removed.txt
new file mode 100644
index 000000000000..d802177e249b
--- /dev/null
+++ b/apex/media/service/api/system-server-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/apex/media/service/java/com/android/server/media/MediaCommunicationService.java b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java
new file mode 100644
index 000000000000..0468fdf30ba8
--- /dev/null
+++ b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.media;
+
+import android.content.Context;
+import android.media.IMediaCommunicationService;
+
+import com.android.server.SystemService;
+
+/**
+ * A system service that managers {@link android.media.MediaSession2} creations
+ * and their ongoing media playback state.
+ * @hide
+ */
+public class MediaCommunicationService extends SystemService {
+
+ public MediaCommunicationService(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(Context.MEDIA_COMMUNICATION_SERVICE, new Stub());
+ }
+
+ private class Stub extends IMediaCommunicationService.Stub {
+ }
+}
diff --git a/core/api/current.txt b/core/api/current.txt
index b49e7247708c..d1b9716b4cd3 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8350,6 +8350,7 @@ package android.appwidget {
method public android.appwidget.AppWidgetProviderInfo clone();
method public int describeContents();
method public final android.os.UserHandle getProfile();
+ method @NonNull public android.content.pm.ActivityInfo getProviderInfo();
method @Nullable public final String loadDescription(@NonNull android.content.Context);
method public final android.graphics.drawable.Drawable loadIcon(@NonNull android.content.Context, int);
method public final String loadLabel(android.content.pm.PackageManager);
@@ -10374,6 +10375,7 @@ package android.content {
field public static final String LAUNCHER_APPS_SERVICE = "launcherapps";
field public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
field public static final String LOCATION_SERVICE = "location";
+ field public static final String MEDIA_COMMUNICATION_SERVICE = "media_communication";
field public static final String MEDIA_METRICS_SERVICE = "media_metrics";
field public static final String MEDIA_PROJECTION_SERVICE = "media_projection";
field public static final String MEDIA_ROUTER_SERVICE = "media_router";
@@ -11867,6 +11869,7 @@ package android.content.pm {
}
public class LauncherActivityInfo {
+ method @NonNull public android.content.pm.ActivityInfo getActivityInfo();
method public android.content.pm.ApplicationInfo getApplicationInfo();
method public android.graphics.drawable.Drawable getBadgedIcon(int);
method public android.content.ComponentName getComponentName();
@@ -12239,6 +12242,7 @@ package android.content.pm {
method @NonNull public abstract android.content.pm.ActivityInfo getReceiverInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public abstract android.content.res.Resources getResourcesForActivity(@NonNull android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public abstract android.content.res.Resources getResourcesForApplication(@NonNull android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull public android.content.res.Resources getResourcesForApplication(@NonNull android.content.pm.ApplicationInfo, @Nullable android.content.res.Configuration) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public abstract android.content.res.Resources getResourcesForApplication(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public abstract android.content.pm.ServiceInfo getServiceInfo(@NonNull android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method @NonNull public abstract java.util.List<android.content.pm.SharedLibraryInfo> getSharedLibraries(int);
@@ -16799,6 +16803,18 @@ package android.graphics.text {
package android.hardware {
+ public abstract class Battery {
+ ctor public Battery();
+ method @FloatRange(from=-1.0F, to=1.0f) public abstract float getCapacity();
+ method public abstract int getStatus();
+ method public abstract boolean hasBattery();
+ field public static final int STATUS_CHARGING = 2; // 0x2
+ field public static final int STATUS_DISCHARGING = 3; // 0x3
+ field public static final int STATUS_FULL = 5; // 0x5
+ field public static final int STATUS_NOT_CHARGING = 4; // 0x4
+ field public static final int STATUS_UNKNOWN = 1; // 0x1
+ }
+
@Deprecated public class Camera {
method @Deprecated public final void addCallbackBuffer(byte[]);
method @Deprecated public final void autoFocus(android.hardware.Camera.AutoFocusCallback);
@@ -18499,6 +18515,7 @@ package android.hardware.input {
public final class InputManager {
method public android.view.InputDevice getInputDevice(int);
method public int[] getInputDeviceIds();
+ method public float getMaximumObscuringOpacityForTouch();
method public void registerInputDeviceListener(android.hardware.input.InputManager.InputDeviceListener, android.os.Handler);
method public void unregisterInputDeviceListener(android.hardware.input.InputManager.InputDeviceListener);
method @Nullable public android.view.VerifiedInputEvent verifyInputEvent(@NonNull android.view.InputEvent);
@@ -25630,8 +25647,6 @@ package android.net {
method public void applyTransportModeTransform(@NonNull java.net.Socket, int, @NonNull android.net.IpSecTransform) throws java.io.IOException;
method public void applyTransportModeTransform(@NonNull java.net.DatagramSocket, int, @NonNull android.net.IpSecTransform) throws java.io.IOException;
method public void applyTransportModeTransform(@NonNull java.io.FileDescriptor, int, @NonNull android.net.IpSecTransform) throws java.io.IOException;
- method @RequiresPermission("android.permission.MANAGE_IPSEC_TUNNELS") public void applyTunnelModeTransform(@NonNull android.net.IpSecManager.IpSecTunnelInterface, int, @NonNull android.net.IpSecTransform) throws java.io.IOException;
- method @NonNull @RequiresPermission("android.permission.MANAGE_IPSEC_TUNNELS") public android.net.IpSecManager.IpSecTunnelInterface createIpSecTunnelInterface(@NonNull android.net.Network) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
method @NonNull public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
method @NonNull public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
method public void removeTransportModeTransforms(@NonNull java.net.Socket) throws java.io.IOException;
@@ -25641,12 +25656,6 @@ package android.net {
field public static final int DIRECTION_OUT = 1; // 0x1
}
- public static final class IpSecManager.IpSecTunnelInterface implements java.lang.AutoCloseable {
- method @RequiresPermission("android.permission.MANAGE_IPSEC_TUNNELS") public void addAddress(@NonNull java.net.InetAddress, int) throws java.io.IOException;
- method public void close();
- method @RequiresPermission("android.permission.MANAGE_IPSEC_TUNNELS") public void removeAddress(@NonNull java.net.InetAddress, int) throws java.io.IOException;
- }
-
public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
}
@@ -46366,6 +46375,7 @@ package android.view {
public final class InputDevice implements android.os.Parcelable {
method public int describeContents();
+ method @NonNull public android.hardware.Battery getBattery();
method public int getControllerNumber();
method public String getDescriptor();
method public static android.view.InputDevice getDevice(int);
@@ -46420,6 +46430,7 @@ package android.view {
field public static final int SOURCE_MOUSE = 8194; // 0x2002
field public static final int SOURCE_MOUSE_RELATIVE = 131076; // 0x20004
field public static final int SOURCE_ROTARY_ENCODER = 4194304; // 0x400000
+ field public static final int SOURCE_SENSOR = 67108864; // 0x4000000
field public static final int SOURCE_STYLUS = 16386; // 0x4002
field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 2b9f1712bd87..e8650faad1f6 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -103,6 +103,7 @@ package android.media {
}
public class MediaServiceManager {
+ method @NonNull public android.media.MediaServiceManager.ServiceRegisterer getMediaCommunicationServiceRegisterer();
method @NonNull public android.media.MediaServiceManager.ServiceRegisterer getMediaSessionServiceRegisterer();
method @NonNull public android.media.MediaServiceManager.ServiceRegisterer getMediaTranscodingServiceRegisterer();
}
@@ -156,6 +157,10 @@ package android.media.session {
package android.net {
+ public final class ConnectivityFrameworkInitializer {
+ method public static void registerServiceWrappers();
+ }
+
public class ConnectivityManager {
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @Nullable android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index f40bf5d9f759..1d13b73b7020 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -138,6 +138,7 @@ package android {
field public static final String MANAGE_ROTATION_RESOLVER = "android.permission.MANAGE_ROTATION_RESOLVER";
field public static final String MANAGE_SEARCH_UI = "android.permission.MANAGE_SEARCH_UI";
field public static final String MANAGE_SENSOR_PRIVACY = "android.permission.MANAGE_SENSOR_PRIVACY";
+ field public static final String MANAGE_SMARTSPACE = "android.permission.MANAGE_SMARTSPACE";
field public static final String MANAGE_SOUND_TRIGGER = "android.permission.MANAGE_SOUND_TRIGGER";
field public static final String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS";
field public static final String MANAGE_TEST_NETWORKS = "android.permission.MANAGE_TEST_NETWORKS";
@@ -1493,6 +1494,169 @@ package android.app.search {
}
+package android.app.smartspace {
+
+ public final class SmartspaceAction implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public CharSequence getContentDescription();
+ method @Nullable public android.os.Bundle getExtras();
+ method @Nullable public android.graphics.drawable.Icon getIcon();
+ method @NonNull public String getId();
+ method @Nullable public android.content.Intent getIntent();
+ method @Nullable public android.app.PendingIntent getPendingIntent();
+ method @Nullable public CharSequence getSubtitle();
+ method @NonNull public CharSequence getTitle();
+ method @Nullable public android.os.UserHandle getUserHandle();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.SmartspaceAction> CREATOR;
+ }
+
+ public static final class SmartspaceAction.Builder {
+ ctor public SmartspaceAction.Builder(@NonNull String, @NonNull String);
+ method @NonNull public android.app.smartspace.SmartspaceAction build();
+ method @NonNull public android.app.smartspace.SmartspaceAction.Builder setContentDescription(@Nullable CharSequence);
+ method @NonNull public android.app.smartspace.SmartspaceAction.Builder setExtras(@Nullable android.os.Bundle);
+ method @NonNull public android.app.smartspace.SmartspaceAction.Builder setIcon(@Nullable android.graphics.drawable.Icon);
+ method @NonNull public android.app.smartspace.SmartspaceAction.Builder setIntent(@Nullable android.content.Intent);
+ method @NonNull public android.app.smartspace.SmartspaceAction.Builder setPendingIntent(@Nullable android.app.PendingIntent);
+ method @NonNull public android.app.smartspace.SmartspaceAction.Builder setSubtitle(@Nullable CharSequence);
+ method @NonNull public android.app.smartspace.SmartspaceAction.Builder setUserHandle(@Nullable android.os.UserHandle);
+ }
+
+ public final class SmartspaceConfig implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public android.os.Bundle getExtras();
+ method @NonNull public String getPackageName();
+ method @NonNull public int getSmartspaceTargetCount();
+ method @NonNull public String getUiSurface();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.SmartspaceConfig> CREATOR;
+ }
+
+ public static final class SmartspaceConfig.Builder {
+ ctor public SmartspaceConfig.Builder(@NonNull android.content.Context, @NonNull String);
+ method @NonNull public android.app.smartspace.SmartspaceConfig build();
+ method @NonNull public android.app.smartspace.SmartspaceConfig.Builder setExtras(@NonNull android.os.Bundle);
+ method @NonNull public android.app.smartspace.SmartspaceConfig.Builder setSmartspaceTargetCount(int);
+ }
+
+ public final class SmartspaceManager {
+ method @NonNull public android.app.smartspace.SmartspaceSession createSmartspaceSession(@NonNull android.app.smartspace.SmartspaceConfig);
+ }
+
+ public final class SmartspaceSession implements java.lang.AutoCloseable {
+ method public void close();
+ method public void destroy();
+ method protected void finalize();
+ method public void notifySmartspaceEvent(@NonNull android.app.smartspace.SmartspaceTargetEvent);
+ method public void registerSmartspaceUpdates(@NonNull java.util.concurrent.Executor, @NonNull android.app.smartspace.SmartspaceSession.Callback);
+ method public void requestSmartspaceUpdate();
+ method public void unregisterSmartspaceUpdates(@NonNull android.app.smartspace.SmartspaceSession.Callback);
+ }
+
+ public static interface SmartspaceSession.Callback {
+ method public void onTargetsAvailable(@NonNull java.util.List<android.app.smartspace.SmartspaceTarget>);
+ }
+
+ public final class SmartspaceSessionId implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public String getId();
+ method @NonNull public int getUserId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.SmartspaceSessionId> CREATOR;
+ }
+
+ public final class SmartspaceTarget implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public java.util.List<android.app.smartspace.SmartspaceAction> getActionChips();
+ method @Nullable public String getAssociatedSmartspaceTargetId();
+ method @Nullable public android.app.smartspace.SmartspaceAction getBaseAction();
+ method @NonNull public android.content.ComponentName getComponentName();
+ method @NonNull public long getCreationTimeMillis();
+ method @NonNull public long getExpiryTimeMillis();
+ method @NonNull public int getFeatureType();
+ method @Nullable public android.app.smartspace.SmartspaceAction getHeaderAction();
+ method @NonNull public java.util.List<android.app.smartspace.SmartspaceAction> getIconGrid();
+ method @NonNull public float getScore();
+ method @Nullable public android.net.Uri getSliceUri();
+ method @NonNull public String getSmartspaceTargetId();
+ method @Nullable public String getSourceNotificationKey();
+ method @NonNull public android.os.UserHandle getUserHandle();
+ method @Nullable public android.appwidget.AppWidgetProviderInfo getWidgetId();
+ method @NonNull public boolean isSensitive();
+ method @NonNull public boolean shouldShowExpanded();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.SmartspaceTarget> CREATOR;
+ field public static final int FEATURE_ALARM = 7; // 0x7
+ field public static final int FEATURE_BEDTIME_ROUTINE = 16; // 0x10
+ field public static final int FEATURE_CALENDAR = 2; // 0x2
+ field public static final int FEATURE_COMMUTE_TIME = 3; // 0x3
+ field public static final int FEATURE_CONSENT = 11; // 0xb
+ field public static final int FEATURE_ETA_MONITORING = 18; // 0x12
+ field public static final int FEATURE_FITNESS_TRACKING = 17; // 0x11
+ field public static final int FEATURE_FLIGHT = 4; // 0x4
+ field public static final int FEATURE_LOYALTY_CARD = 14; // 0xe
+ field public static final int FEATURE_MEDIA = 15; // 0xf
+ field public static final int FEATURE_MISSED_CALL = 19; // 0x13
+ field public static final int FEATURE_ONBOARDING = 8; // 0x8
+ field public static final int FEATURE_PACKAGE_TRACKING = 20; // 0x14
+ field public static final int FEATURE_REMINDER = 6; // 0x6
+ field public static final int FEATURE_SHOPPING_LIST = 13; // 0xd
+ field public static final int FEATURE_SPORTS = 9; // 0x9
+ field public static final int FEATURE_STOCK_PRICE_CHANGE = 12; // 0xc
+ field public static final int FEATURE_STOPWATCH = 22; // 0x16
+ field public static final int FEATURE_TIMER = 21; // 0x15
+ field public static final int FEATURE_TIPS = 5; // 0x5
+ field public static final int FEATURE_UNDEFINED = 0; // 0x0
+ field public static final int FEATURE_UPCOMING_ALARM = 23; // 0x17
+ field public static final int FEATURE_WEATHER = 1; // 0x1
+ field public static final int FEATURE_WEATHER_ALERT = 10; // 0xa
+ }
+
+ public static final class SmartspaceTarget.Builder {
+ ctor public SmartspaceTarget.Builder(@NonNull String, @NonNull android.content.ComponentName, @NonNull android.os.UserHandle);
+ method @NonNull public android.app.smartspace.SmartspaceTarget build();
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setActionChips(@NonNull java.util.List<android.app.smartspace.SmartspaceAction>);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setAssociatedSmartspaceTargetId(@NonNull String);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setBaseAction(@NonNull android.app.smartspace.SmartspaceAction);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setCreationTimeMillis(@NonNull long);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setExpiryTimeMillis(@NonNull long);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setFeatureType(@NonNull int);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setHeaderAction(@NonNull android.app.smartspace.SmartspaceAction);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setIconGrid(@NonNull java.util.List<android.app.smartspace.SmartspaceAction>);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setScore(@NonNull float);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setSensitive(@NonNull boolean);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setShouldShowExpanded(@NonNull boolean);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setSliceUri(@NonNull android.net.Uri);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setSourceNotificationKey(@NonNull String);
+ method @NonNull public android.app.smartspace.SmartspaceTarget.Builder setWidgetId(@NonNull android.appwidget.AppWidgetProviderInfo);
+ }
+
+ public final class SmartspaceTargetEvent implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public int getEventType();
+ method @Nullable public String getSmartspaceActionId();
+ method @Nullable public android.app.smartspace.SmartspaceTarget getSmartspaceTarget();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.SmartspaceTargetEvent> CREATOR;
+ field public static final int EVENT_TARGET_BLOCK = 5; // 0x5
+ field public static final int EVENT_TARGET_DISMISS = 4; // 0x4
+ field public static final int EVENT_TARGET_INTERACTION = 1; // 0x1
+ field public static final int EVENT_TARGET_IN_VIEW = 2; // 0x2
+ field public static final int EVENT_TARGET_OUT_OF_VIEW = 3; // 0x3
+ field public static final int EVENT_UI_SURFACE_IN_VIEW = 6; // 0x6
+ field public static final int EVENT_UI_SURFACE_OUT_OF_VIEW = 7; // 0x7
+ }
+
+ public static final class SmartspaceTargetEvent.Builder {
+ ctor public SmartspaceTargetEvent.Builder(int);
+ method @NonNull public android.app.smartspace.SmartspaceTargetEvent build();
+ method @NonNull public android.app.smartspace.SmartspaceTargetEvent.Builder setSmartspaceActionId(@NonNull String);
+ method @NonNull public android.app.smartspace.SmartspaceTargetEvent.Builder setSmartspaceTarget(@NonNull android.app.smartspace.SmartspaceTarget);
+ }
+
+}
+
package android.app.time {
public final class TimeManager {
@@ -1955,6 +2119,7 @@ package android.content {
field public static final String ROLLBACK_SERVICE = "rollback";
field public static final String SEARCH_UI_SERVICE = "search_ui";
field public static final String SECURE_ELEMENT_SERVICE = "secure_element";
+ field public static final String SMARTSPACE_SERVICE = "smartspace";
field public static final String STATS_MANAGER = "stats";
field public static final String STATUS_BAR_SERVICE = "statusbar";
field public static final String SYSTEM_CONFIG_SERVICE = "system_config";
@@ -3183,6 +3348,7 @@ package android.hardware.location {
public class ContextHubClientCallback {
ctor public ContextHubClientCallback();
+ method public void onClientAuthorizationChanged(@NonNull android.hardware.location.ContextHubClient, long, int);
method public void onHubReset(android.hardware.location.ContextHubClient);
method public void onMessageFromNanoApp(android.hardware.location.ContextHubClient, android.hardware.location.NanoAppMessage);
method public void onNanoAppAborted(android.hardware.location.ContextHubClient, long, int);
@@ -3219,6 +3385,7 @@ package android.hardware.location {
public class ContextHubIntentEvent {
method @NonNull public static android.hardware.location.ContextHubIntentEvent fromIntent(@NonNull android.content.Intent);
+ method public int getClientAuthorizationState();
method @NonNull public android.hardware.location.ContextHubInfo getContextHubInfo();
method public int getEventType();
method public int getNanoAppAbortCode();
@@ -3227,8 +3394,10 @@ package android.hardware.location {
}
public final class ContextHubManager {
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubClient createClient(@Nullable android.content.Context, @NonNull android.hardware.location.ContextHubInfo, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.location.ContextHubClientCallback);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.ContextHubClientCallback, @NonNull java.util.concurrent.Executor);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.ContextHubClientCallback);
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubClient createClient(@Nullable android.content.Context, @NonNull android.hardware.location.ContextHubInfo, @NonNull android.app.PendingIntent, long);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.app.PendingIntent, long);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubTransaction<java.lang.Void> disableNanoApp(@NonNull android.hardware.location.ContextHubInfo, long);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubTransaction<java.lang.Void> enableNanoApp(@NonNull android.hardware.location.ContextHubInfo, long);
@@ -3246,6 +3415,10 @@ package android.hardware.location {
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public int unloadNanoApp(int);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, 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);
+ 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
+ field public static final int EVENT_CLIENT_AUTHORIZATION = 7; // 0x7
field public static final int EVENT_HUB_RESET = 6; // 0x6
field public static final int EVENT_NANOAPP_ABORTED = 4; // 0x4
field public static final int EVENT_NANOAPP_DISABLED = 3; // 0x3
@@ -3253,6 +3426,7 @@ package android.hardware.location {
field public static final int EVENT_NANOAPP_LOADED = 0; // 0x0
field public static final int EVENT_NANOAPP_MESSAGE = 5; // 0x5
field public static final int EVENT_NANOAPP_UNLOADED = 1; // 0x1
+ field public static final String EXTRA_CLIENT_AUTHORIZATION_STATE = "android.hardware.location.extra.CLIENT_AUTHORIZATION_STATE";
field public static final String EXTRA_CONTEXT_HUB_INFO = "android.hardware.location.extra.CONTEXT_HUB_INFO";
field public static final String EXTRA_EVENT_TYPE = "android.hardware.location.extra.EVENT_TYPE";
field public static final String EXTRA_MESSAGE = "android.hardware.location.extra.MESSAGE";
@@ -3491,8 +3665,10 @@ package android.hardware.location {
public final class NanoAppState implements android.os.Parcelable {
ctor public NanoAppState(long, int, boolean);
+ ctor public NanoAppState(long, int, boolean, @NonNull java.util.List<java.lang.String>);
method public int describeContents();
method public long getNanoAppId();
+ method @NonNull public java.util.List<java.lang.String> getNanoAppPermissions();
method public long getNanoAppVersion();
method public boolean isEnabled();
method public void writeToParcel(android.os.Parcel, int);
@@ -5817,6 +5993,7 @@ package android.media.tv.tuner.filter {
public final class RestartEvent extends android.media.tv.tuner.filter.FilterEvent {
method public int getStartId();
+ field public static final int NEW_FILTER_FIRST_START_ID = 0; // 0x0
}
public final class ScramblingStatusEvent extends android.media.tv.tuner.filter.FilterEvent {
@@ -6951,11 +7128,15 @@ package android.net {
}
public final class IpSecManager {
- method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecManager.IpSecTunnelInterface createIpSecTunnelInterface(@NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull android.net.Network) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+ method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void applyTunnelModeTransform(@NonNull android.net.IpSecManager.IpSecTunnelInterface, int, @NonNull android.net.IpSecTransform) throws java.io.IOException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecManager.IpSecTunnelInterface createIpSecTunnelInterface(@NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull android.net.Network) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
}
public static final class IpSecManager.IpSecTunnelInterface implements java.lang.AutoCloseable {
+ method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void addAddress(@NonNull java.net.InetAddress, int) throws java.io.IOException;
+ method public void close();
method @NonNull public String getInterfaceName();
+ method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void removeAddress(@NonNull java.net.InetAddress, int) throws java.io.IOException;
}
public static class IpSecTransform.Builder {
@@ -8896,6 +9077,7 @@ package android.provider {
field @Deprecated public static final String NAMESPACE_STORAGE = "storage";
field public static final String NAMESPACE_STORAGE_NATIVE_BOOT = "storage_native_boot";
field public static final String NAMESPACE_SYSTEMUI = "systemui";
+ field public static final String NAMESPACE_SYSTEM_TIME = "system_time";
field public static final String NAMESPACE_TELEPHONY = "telephony";
field public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
field public static final String NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT = "window_manager_native_boot";
@@ -9845,6 +10027,7 @@ package android.service.notification {
method public void onNotificationDirectReplied(@NonNull String);
method @Nullable public abstract android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification);
method @Nullable public android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification, @NonNull android.app.NotificationChannel);
+ method @Nullable public android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification, @NonNull android.app.NotificationChannel, @NonNull android.service.notification.NotificationListenerService.RankingMap);
method public void onNotificationExpansionChanged(@NonNull String, boolean, boolean);
method public abstract void onNotificationSnoozedUntilContext(@NonNull android.service.notification.StatusBarNotification, @NonNull String);
method public void onNotificationVisibilityChanged(@NonNull String, boolean);
@@ -10070,6 +10253,21 @@ package android.service.settings.suggestions {
}
+package android.service.smartspace {
+
+ public abstract class SmartspaceService extends android.app.Service {
+ ctor public SmartspaceService();
+ method @MainThread public abstract void notifySmartspaceEvent(@NonNull android.app.smartspace.SmartspaceSessionId, @NonNull android.app.smartspace.SmartspaceTargetEvent);
+ method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
+ method public abstract void onCreateSmartspaceSession(@NonNull android.app.smartspace.SmartspaceConfig, @NonNull android.app.smartspace.SmartspaceSessionId);
+ method @MainThread public abstract void onDestroy(@NonNull android.app.smartspace.SmartspaceSessionId);
+ method public abstract void onDestroySmartspaceSession(@NonNull android.app.smartspace.SmartspaceSessionId);
+ method @MainThread public abstract void onRequestSmartspaceUpdate(@NonNull android.app.smartspace.SmartspaceSessionId);
+ method public final void updateSmartspaceTargets(@NonNull android.app.smartspace.SmartspaceSessionId, @NonNull java.util.List<android.app.smartspace.SmartspaceTarget>);
+ }
+
+}
+
package android.service.storage {
public abstract class ExternalStorageService extends android.app.Service {
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index 8b3cee403bca..58f6c52d2b05 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -6,9 +6,11 @@ ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
BuilderSetStyle: android.net.IpSecTransform.Builder#buildTunnelModeTransform(java.net.InetAddress, android.net.IpSecManager.SecurityParameterIndex):
Builder methods names should use setFoo() / addFoo() / clearFoo() style: method android.net.IpSecTransform.Builder.buildTunnelModeTransform(java.net.InetAddress,android.net.IpSecManager.SecurityParameterIndex)
+
ExecutorRegistration: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
Registration methods should have overload that accepts delivery Executor: `setOnRtpRxNoticeListener`
-
+
+
GenericException: android.app.prediction.AppPredictor#finalize():
GenericException: android.hardware.location.ContextHubClient#finalize():
@@ -21,6 +23,8 @@ GenericException: android.service.autofill.augmented.FillWindow#finalize():
IntentBuilderName: android.app.search.SearchAction#getIntent():
+IntentBuilderName: android.app.smartspace.SmartspaceAction#getIntent():
+ Methods creating an Intent should be named `create<Foo>Intent()`, was `getIntent`
KotlinKeyword: android.app.Notification#when:
@@ -83,6 +87,10 @@ MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(
+OnNameExpected: android.service.smartspace.SmartspaceService#notifySmartspaceEvent(android.app.smartspace.SmartspaceSessionId, android.app.smartspace.SmartspaceTargetEvent):
+ Methods implemented by developers should follow the on<Something> style, was `notifySmartspaceEvent`
+
+
ProtectedMember: android.printservice.recommendation.RecommendationService#attachBaseContext(android.content.Context):
ProtectedMember: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
@@ -187,11 +195,10 @@ SamShouldBeLast: android.media.AudioRecordingMonitor#registerAudioRecordingCallb
SamShouldBeLast: android.media.AudioRouting#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
-SamShouldBeLast: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
- SAM-compatible parameters (such as parameter 2, "listener", in android.media.MediaPlayer.setOnRtpRxNoticeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
-
SamShouldBeLast: android.media.AudioTrack#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
+SamShouldBeLast: android.media.MediaPlayer#setOnRtpRxNoticeListener(android.content.Context, android.media.MediaPlayer.OnRtpRxNoticeListener, android.os.Handler):
+ SAM-compatible parameters (such as parameter 2, "listener", in android.media.MediaPlayer.setOnRtpRxNoticeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
SamShouldBeLast: android.media.MediaRecorder#addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler):
SamShouldBeLast: android.media.MediaRecorder#registerAudioRecordingCallback(java.util.concurrent.Executor, android.media.AudioManager.AudioRecordingCallback):
@@ -258,3 +265,5 @@ UserHandleName: android.app.search.SearchAction.Builder#setUserHandle(android.os
Method taking UserHandle should be named `doFooAsUser` or `queryFooForUser`, was `setUserHandle`
UserHandleName: android.app.search.SearchTarget.Builder#setUserHandle(android.os.UserHandle):
+UserHandleName: android.app.smartspace.SmartspaceAction.Builder#setUserHandle(android.os.UserHandle):
+ Method taking UserHandle should be named `doFooAsUser` or `queryFooForUser`, was `setUserHandle`
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 445824a129ac..bc1858b63783 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -944,9 +944,8 @@ package android.hardware.input {
public final class InputManager {
method public int getBlockUntrustedTouchesMode(@NonNull android.content.Context);
- method public float getMaximumObscuringOpacityForTouch(@NonNull android.content.Context);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setBlockUntrustedTouchesMode(@NonNull android.content.Context, int);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(@NonNull android.content.Context, float);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(float);
field public static final long BLOCK_UNTRUSTED_TOUCHES = 158002302L; // 0x96aec7eL
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9b141b7bc649..1f9cb6430a5d 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2291,9 +2291,10 @@ public final class ActivityThread extends ClientTransactionHandler {
* Resources if one has already been created.
*/
Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
- String[] libDirs, LoadedApk pkgInfo) {
+ String[] libDirs, LoadedApk pkgInfo, Configuration overrideConfig) {
return mResourcesManager.getResources(null, resDir, splitResDirs, overlayDirs, libDirs,
- null, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader(), null);
+ null, overrideConfig, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader(),
+ null);
}
@UnsupportedAppUsage
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index d716a3cf5445..7410a1ca04c8 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -50,7 +50,7 @@ import java.util.zip.GZIPInputStream;
*
* <p>
* Application process could die for many reasons, for example {@link #REASON_LOW_MEMORY}
- * when it was killed by the ystem because it was running low on memory. Reason
+ * when it was killed by the system because it was running low on memory. Reason
* of the death can be retrieved via {@link #getReason}. Besides the reason, there are a few other
* auxiliary APIs like {@link #getStatus} and {@link #getImportance} to help the caller with
* additional diagnostic information.
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 77542bda22a0..7e7f887766e2 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -70,6 +70,7 @@ import android.content.pm.SuspendDialogInfo;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VersionedPackage;
import android.content.pm.dex.ArtManager;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.Bitmap;
@@ -1691,20 +1692,29 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
throws NameNotFoundException {
+ return getResourcesForApplication(app, null);
+ }
+
+ @Override
+ public Resources getResourcesForApplication(@NonNull ApplicationInfo app,
+ @Nullable Configuration configuration) throws NameNotFoundException {
if (app.packageName.equals("system")) {
- return mContext.mMainThread.getSystemUiContext().getResources();
+ Context sysuiContext = mContext.mMainThread.getSystemUiContext();
+ if (configuration != null) {
+ sysuiContext = sysuiContext.createConfigurationContext(configuration);
+ }
+ return sysuiContext.getResources();
}
final boolean sameUid = (app.uid == Process.myUid());
final Resources r = mContext.mMainThread.getTopLevelResources(
- sameUid ? app.sourceDir : app.publicSourceDir,
- sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
- app.resourceDirs, app.sharedLibraryFiles,
- mContext.mPackageInfo);
+ sameUid ? app.sourceDir : app.publicSourceDir,
+ sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
+ app.resourceDirs, app.sharedLibraryFiles,
+ mContext.mPackageInfo, configuration);
if (r != null) {
return r;
}
throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
-
}
@Override
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 534f3e25acde..671315f37b20 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -21,6 +21,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemApi.Client;
import android.annotation.TestApi;
@@ -1275,6 +1276,7 @@ public final class PendingIntent implements Parcelable {
* @param flags MATCH_* flags from {@link android.content.pm.PackageManager}.
* @hide
*/
+ @SuppressLint("NullableCollection")
@RequiresPermission(permission.GET_INTENT_SENDER_INTENT)
@SystemApi(client = Client.MODULE_LIBRARIES)
@TestApi
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 1498dae764a9..f05c7b58e202 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -34,6 +34,7 @@ import android.app.prediction.AppPredictionManager;
import android.app.role.RoleFrameworkInitializer;
import android.app.search.SearchUiManager;
import android.app.slice.SliceManager;
+import android.app.smartspace.SmartspaceManager;
import android.app.time.TimeManager;
import android.app.timedetector.TimeDetector;
import android.app.timedetector.TimeDetectorImpl;
@@ -120,21 +121,16 @@ import android.media.tv.ITvInputManager;
import android.media.tv.TvInputManager;
import android.media.tv.tunerresourcemanager.ITunerResourceManager;
import android.media.tv.tunerresourcemanager.TunerResourceManager;
-import android.net.ConnectivityDiagnosticsManager;
-import android.net.ConnectivityManager;
+import android.net.ConnectivityFrameworkInitializer;
import android.net.EthernetManager;
-import android.net.IConnectivityManager;
import android.net.IEthernetManager;
import android.net.IIpSecService;
import android.net.INetworkPolicyManager;
-import android.net.ITestNetworkManager;
import android.net.IpSecManager;
import android.net.NetworkPolicyManager;
import android.net.NetworkScoreManager;
import android.net.NetworkWatchlistManager;
-import android.net.TestNetworkManager;
import android.net.TetheringManager;
-import android.net.VpnManager;
import android.net.lowpan.ILowpanManager;
import android.net.lowpan.LowpanManager;
import android.net.nsd.INsdManager;
@@ -163,7 +159,6 @@ import android.os.IUserManager;
import android.os.IncidentManager;
import android.os.PowerManager;
import android.os.RecoverySystem;
-import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
import android.os.StatsFrameworkInitializer;
@@ -370,15 +365,6 @@ public final class SystemServiceRegistry {
// (which extends it).
SYSTEM_SERVICE_NAMES.put(android.text.ClipboardManager.class, Context.CLIPBOARD_SERVICE);
- registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class,
- new StaticApplicationContextServiceFetcher<ConnectivityManager>() {
- @Override
- public ConnectivityManager createService(Context context) throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);
- IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
- return new ConnectivityManager(context, service);
- }});
-
registerService(Context.NETD_SERVICE, IBinder.class, new StaticServiceFetcher<IBinder>() {
@Override
public IBinder createService() throws ServiceNotFoundException {
@@ -412,50 +398,6 @@ public final class SystemServiceRegistry {
return new IpSecManager(ctx, service);
}});
- registerService(Context.VPN_MANAGEMENT_SERVICE, VpnManager.class,
- new CachedServiceFetcher<VpnManager>() {
- @Override
- public VpnManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
- IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
- return new VpnManager(ctx, service);
- }});
-
- registerService(Context.CONNECTIVITY_DIAGNOSTICS_SERVICE,
- ConnectivityDiagnosticsManager.class,
- new CachedServiceFetcher<ConnectivityDiagnosticsManager>() {
- @Override
- public ConnectivityDiagnosticsManager createService(ContextImpl ctx)
- throws ServiceNotFoundException {
- // ConnectivityDiagnosticsManager is backed by ConnectivityService
- IBinder b = ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);
- IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
- return new ConnectivityDiagnosticsManager(ctx, service);
- }});
-
- registerService(
- Context.TEST_NETWORK_SERVICE,
- TestNetworkManager.class,
- new StaticApplicationContextServiceFetcher<TestNetworkManager>() {
- @Override
- public TestNetworkManager createService(Context context)
- throws ServiceNotFoundException {
- IBinder csBinder =
- ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE);
- IConnectivityManager csMgr =
- IConnectivityManager.Stub.asInterface(csBinder);
-
- final IBinder tnBinder;
- try {
- tnBinder = csMgr.startOrGetTestNetworkService();
- } catch (RemoteException e) {
- throw new ServiceNotFoundException(Context.TEST_NETWORK_SERVICE);
- }
- ITestNetworkManager tnMgr = ITestNetworkManager.Stub.asInterface(tnBinder);
- return new TestNetworkManager(tnMgr);
- }
- });
-
registerService(Context.COUNTRY_DETECTOR, CountryDetector.class,
new StaticServiceFetcher<CountryDetector>() {
@Override
@@ -1224,6 +1166,16 @@ public final class SystemServiceRegistry {
}
});
+ registerService(Context.SMARTSPACE_SERVICE, SmartspaceManager.class,
+ new CachedServiceFetcher<SmartspaceManager>() {
+ @Override
+ public SmartspaceManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getService(Context.SMARTSPACE_SERVICE);
+ return b == null ? null : new SmartspaceManager(ctx);
+ }
+ });
+
registerService(Context.APP_PREDICTION_SERVICE, AppPredictionManager.class,
new CachedServiceFetcher<AppPredictionManager>() {
@Override
@@ -1441,6 +1393,7 @@ public final class SystemServiceRegistry {
try {
// Note: the following functions need to be @SystemApis, once they become mainline
// modules.
+ ConnectivityFrameworkInitializer.registerServiceWrappers();
JobSchedulerFrameworkInitializer.registerServiceWrappers();
BlobStoreManagerFrameworkInitializer.initialize();
TelephonyFrameworkInitializer.registerServiceWrappers();
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 623c878d7bfa..e31e0243cae0 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -36,7 +36,6 @@ import android.window.TaskSnapshot;
import android.window.WindowContainerToken;
import java.util.ArrayList;
-import java.util.List;
import java.util.Objects;
/**
@@ -180,6 +179,19 @@ public class TaskInfo {
public ActivityInfo topActivityInfo;
/**
+ * The top activity in this task.
+ * @hide
+ */
+ @Nullable
+ public IBinder topActivityToken;
+
+ /**
+ * Whether the direct top activity is in size compat mode on foreground.
+ * @hide
+ */
+ public boolean topActivityInSizeCompat;
+
+ /**
* Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity
* supports), this is what the system actually uses for resizability based on other policy and
* developer options.
@@ -356,6 +368,8 @@ public class TaskInfo {
parentTaskId = source.readInt();
isFocused = source.readBoolean();
isVisible = source.readBoolean();
+ topActivityToken = source.readStrongBinder();
+ topActivityInSizeCompat = source.readBoolean();
}
/**
@@ -391,6 +405,8 @@ public class TaskInfo {
dest.writeInt(parentTaskId);
dest.writeBoolean(isFocused);
dest.writeBoolean(isVisible);
+ dest.writeStrongBinder(topActivityToken);
+ dest.writeBoolean(topActivityInSizeCompat);
}
@Override
@@ -415,6 +431,8 @@ public class TaskInfo {
+ " parentTaskId=" + parentTaskId
+ " isFocused=" + isFocused
+ " isVisible=" + isVisible
+ + " topActivityToken=" + topActivityToken
+ + " topActivityInSizeCompat=" + topActivityInSizeCompat
+ "}";
}
}
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 65a21640bb98..2b52875f4b0b 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -2,6 +2,7 @@ package android.app.assist;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.app.Activity;
import android.content.ComponentName;
@@ -1542,6 +1543,7 @@ public class AssistStructure implements Parcelable {
* {@link View#getOnReceiveContentMimeTypes()} for details.
*/
@Nullable
+ @SuppressLint("NullableCollection")
public String[] getOnReceiveContentMimeTypes() {
return mOnReceiveContentMimeTypes;
}
diff --git a/core/java/android/app/search/Query.java b/core/java/android/app/search/Query.java
index 447ca314b99b..3ab20bb30b22 100644
--- a/core/java/android/app/search/Query.java
+++ b/core/java/android/app/search/Query.java
@@ -17,6 +17,7 @@ package android.app.search;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.os.Bundle;
import android.os.Parcel;
@@ -46,6 +47,7 @@ public final class Query implements Parcelable {
public Query(@NonNull String input,
long timestamp,
+ @SuppressLint("NullableCollection")
@Nullable Bundle extras) {
mInput = input;
mTimestamp = timestamp;
@@ -69,6 +71,7 @@ public final class Query implements Parcelable {
}
@Nullable
+ @SuppressLint("NullableCollection")
public Bundle getExtras() {
return mExtras;
}
diff --git a/core/java/android/app/search/SearchAction.java b/core/java/android/app/search/SearchAction.java
index a76154af63b6..9e40e7ebaef0 100644
--- a/core/java/android/app/search/SearchAction.java
+++ b/core/java/android/app/search/SearchAction.java
@@ -18,6 +18,7 @@ package android.app.search;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.app.PendingIntent;
import android.content.Intent;
@@ -167,6 +168,7 @@ public final class SearchAction implements Parcelable {
/**
* Returns the extra bundle for this object.
*/
+ @SuppressLint("NullableCollection")
public @Nullable Bundle getExtras() {
return mExtras;
}
@@ -325,7 +327,8 @@ public final class SearchAction implements Parcelable {
* Sets the extra.
*/
@NonNull
- public SearchAction.Builder setExtras(@Nullable Bundle extras) {
+ public SearchAction.Builder setExtras(
+ @SuppressLint("NullableCollection") @Nullable Bundle extras) {
mExtras = extras;
return this;
}
diff --git a/core/java/android/app/search/SearchContext.java b/core/java/android/app/search/SearchContext.java
index 9bf766dc8668..548b7daff3a6 100644
--- a/core/java/android/app/search/SearchContext.java
+++ b/core/java/android/app/search/SearchContext.java
@@ -17,6 +17,7 @@ package android.app.search;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.os.Bundle;
import android.os.Parcel;
@@ -52,7 +53,7 @@ public final class SearchContext implements Parcelable {
public SearchContext(int resultTypes,
int queryTimeoutMillis,
- @Nullable Bundle extras) {
+ @SuppressLint("NullableCollection") @Nullable Bundle extras) {
mResultTypes = resultTypes;
mTimeoutMillis = queryTimeoutMillis;
mExtras = extras;
@@ -83,6 +84,7 @@ public final class SearchContext implements Parcelable {
}
@Nullable
+ @SuppressLint("NullableCollection")
public Bundle getExtras() {
return mExtras;
}
diff --git a/core/java/android/app/search/SearchTarget.java b/core/java/android/app/search/SearchTarget.java
index cac22d81c67b..6a80f8bd222a 100644
--- a/core/java/android/app/search/SearchTarget.java
+++ b/core/java/android/app/search/SearchTarget.java
@@ -17,6 +17,7 @@ package android.app.search;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.appwidget.AppWidgetProviderInfo;
import android.content.pm.ShortcutInfo;
@@ -224,6 +225,7 @@ public final class SearchTarget implements Parcelable {
* Return extra bundle.
*/
@Nullable
+ @SuppressLint("NullableCollection")
public Bundle getExtras() {
return mExtras;
}
@@ -386,7 +388,7 @@ public final class SearchTarget implements Parcelable {
* TODO: add comment
*/
@NonNull
- public Builder setExtras(@Nullable Bundle extras) {
+ public Builder setExtras(@SuppressLint("NullableCollection") @Nullable Bundle extras) {
mExtras = extras;
return this;
}
diff --git a/core/java/android/app/smartspace/ISmartspaceCallback.aidl b/core/java/android/app/smartspace/ISmartspaceCallback.aidl
new file mode 100644
index 000000000000..df105f9db7c1
--- /dev/null
+++ b/core/java/android/app/smartspace/ISmartspaceCallback.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace;
+
+import android.content.pm.ParceledListSlice;
+
+/**
+ * @hide
+ */
+oneway interface ISmartspaceCallback {
+
+ void onResult(in ParceledListSlice result);
+}
diff --git a/core/java/android/app/smartspace/ISmartspaceManager.aidl b/core/java/android/app/smartspace/ISmartspaceManager.aidl
new file mode 100644
index 000000000000..e7ec8891ea83
--- /dev/null
+++ b/core/java/android/app/smartspace/ISmartspaceManager.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace;
+
+import android.app.smartspace.SmartspaceTarget;
+import android.app.smartspace.SmartspaceTargetEvent;
+import android.app.smartspace.SmartspaceSessionId;
+import android.app.smartspace.SmartspaceConfig;
+import android.app.smartspace.ISmartspaceCallback;
+import android.content.pm.ParceledListSlice;
+
+/**
+ * @hide
+ */
+interface ISmartspaceManager {
+
+ void createSmartspaceSession(in SmartspaceConfig config, in SmartspaceSessionId sessionId,
+ in IBinder token);
+
+ void notifySmartspaceEvent(in SmartspaceSessionId sessionId, in SmartspaceTargetEvent event);
+
+ void requestSmartspaceUpdate(in SmartspaceSessionId sessionId);
+
+ void registerSmartspaceUpdates(in SmartspaceSessionId sessionId,
+ in ISmartspaceCallback callback);
+
+ void unregisterSmartspaceUpdates(in SmartspaceSessionId sessionId,
+ in ISmartspaceCallback callback);
+
+ void destroySmartspaceSession(in SmartspaceSessionId sessionId);
+}
diff --git a/core/java/android/app/smartspace/SmartspaceAction.java b/core/java/android/app/smartspace/SmartspaceAction.java
new file mode 100644
index 000000000000..033cda1ba845
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceAction.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+import android.text.TextUtils;
+
+import java.util.Objects;
+
+/**
+ * A {@link SmartspaceAction} represents an action which can be taken by a user by tapping on either
+ * the title, the subtitle or on the icon. Supported instances are Intents, PendingIntents or a
+ * ShortcutInfo (by putting the ShortcutInfoId in the bundle). These actions can be called from
+ * another process or within the client process.
+ *
+ * Clients can also receive conditional Intents/PendingIntents in the extras bundle which are
+ * supposed to be fired when the conditions are met. For example, a user can invoke a dismiss/block
+ * action on a game score card but the intention is to only block the team and not the entire
+ * feature.
+ *
+ * @hide
+ */
+@SystemApi
+public final class SmartspaceAction implements Parcelable {
+
+ private static final String TAG = "SmartspaceAction";
+
+ /** A unique Id of this {@link SmartspaceAction}. */
+ @NonNull
+ private final String mId;
+
+ /** An Icon which can be displayed in the UI. */
+ @Nullable
+ private final Icon mIcon;
+
+ /** Title associated with an action. */
+ @NonNull
+ private final CharSequence mTitle;
+
+ /** Subtitle associated with an action. */
+ @Nullable
+ private final CharSequence mSubtitle;
+
+ @Nullable
+ private final CharSequence mContentDescription;
+
+ @Nullable
+ private final PendingIntent mPendingIntent;
+
+ @Nullable
+ private final Intent mIntent;
+
+ @Nullable
+ private final UserHandle mUserHandle;
+
+ @Nullable
+ private Bundle mExtras;
+
+ SmartspaceAction(Parcel in) {
+ mId = in.readString();
+ mIcon = in.readTypedObject(Icon.CREATOR);
+ mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ mSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ mPendingIntent = in.readTypedObject(PendingIntent.CREATOR);
+ mIntent = in.readTypedObject(Intent.CREATOR);
+ mUserHandle = in.readTypedObject(UserHandle.CREATOR);
+ mExtras = in.readTypedObject(Bundle.CREATOR);
+ }
+
+ private SmartspaceAction(
+ @NonNull String id,
+ @Nullable Icon icon,
+ @NonNull CharSequence title,
+ @Nullable CharSequence subtitle,
+ @Nullable CharSequence contentDescription,
+ @Nullable PendingIntent pendingIntent,
+ @Nullable Intent intent,
+ @Nullable UserHandle userHandle,
+ @Nullable Bundle extras) {
+ mId = Objects.requireNonNull(id);
+ mIcon = icon;
+ mTitle = Objects.requireNonNull(title);
+ mSubtitle = subtitle;
+ mContentDescription = contentDescription;
+ mPendingIntent = pendingIntent;
+ mIntent = intent;
+ mUserHandle = userHandle;
+ mExtras = extras;
+ }
+
+ /**
+ * Returns the unique id of this object.
+ */
+ public @NonNull String getId() {
+ return mId;
+ }
+
+ /**
+ * Returns an icon representing the action.
+ */
+ public @Nullable Icon getIcon() {
+ return mIcon;
+ }
+
+ /**
+ * Returns a title representing the action.
+ */
+ public @NonNull CharSequence getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * Returns a subtitle representing the action.
+ */
+ public @Nullable CharSequence getSubtitle() {
+ return mSubtitle;
+ }
+
+ /**
+ * Returns a content description representing the action.
+ */
+ public @Nullable CharSequence getContentDescription() {
+ return mContentDescription;
+ }
+
+ /**
+ * Returns the action intent.
+ */
+ public @Nullable PendingIntent getPendingIntent() {
+ return mPendingIntent;
+ }
+
+ /**
+ * Returns the intent.
+ */
+ public @Nullable Intent getIntent() {
+ return mIntent;
+ }
+
+ /**
+ * Returns the user handle.
+ */
+ public @Nullable UserHandle getUserHandle() {
+ return mUserHandle;
+ }
+
+ /**
+ * Returns the extra bundle for this object.
+ */
+ public @Nullable Bundle getExtras() {
+ return mExtras;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof SmartspaceAction)) return false;
+ SmartspaceAction that = (SmartspaceAction) o;
+ return mId.equals(that.mId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel out, int flags) {
+ out.writeString(mId);
+ out.writeTypedObject(mIcon, flags);
+ TextUtils.writeToParcel(mTitle, out, flags);
+ TextUtils.writeToParcel(mSubtitle, out, flags);
+ TextUtils.writeToParcel(mContentDescription, out, flags);
+ out.writeTypedObject(mPendingIntent, flags);
+ out.writeTypedObject(mIntent, flags);
+ out.writeTypedObject(mUserHandle, flags);
+ out.writeBundle(mExtras);
+ }
+
+ @Override
+ public String toString() {
+ return "SmartspaceAction{"
+ + "mId='" + mId + '\''
+ + ", mIcon=" + mIcon
+ + ", mTitle=" + mTitle
+ + ", mSubtitle=" + mSubtitle
+ + ", mContentDescription=" + mContentDescription
+ + ", mPendingIntent=" + mPendingIntent
+ + ", mIntent=" + mIntent
+ + ", mUserHandle=" + mUserHandle
+ + ", mExtras=" + mExtras
+ + '}';
+ }
+
+ public static final @NonNull Creator<SmartspaceAction> CREATOR =
+ new Creator<SmartspaceAction>() {
+ public SmartspaceAction createFromParcel(Parcel in) {
+ return new SmartspaceAction(in);
+ }
+ public SmartspaceAction[] newArray(int size) {
+ return new SmartspaceAction[size];
+ }
+ };
+
+ /**
+ * A builder for Smartspace action object.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final class Builder {
+ @NonNull
+ private String mId;
+
+ @Nullable
+ private Icon mIcon;
+
+ @NonNull
+ private CharSequence mTitle;
+
+ @Nullable
+ private CharSequence mSubtitle;
+
+ @Nullable
+ private CharSequence mContentDescription;
+
+ @Nullable
+ private PendingIntent mPendingIntent;
+
+ @Nullable
+ private Intent mIntent;
+
+ @Nullable
+ private UserHandle mUserHandle;
+
+ @Nullable
+ private Bundle mExtras;
+
+ /**
+ * Id and title are required.
+ */
+ public Builder(@NonNull String id, @NonNull String title) {
+ mId = Objects.requireNonNull(id);
+ mTitle = Objects.requireNonNull(title);
+ }
+
+ /**
+ * Sets the icon.
+ */
+ @NonNull
+ public Builder setIcon(
+ @Nullable Icon icon) {
+ mIcon = icon;
+ return this;
+ }
+
+ /**
+ * Sets the subtitle.
+ */
+ @NonNull
+ public Builder setSubtitle(
+ @Nullable CharSequence subtitle) {
+ mSubtitle = subtitle;
+ return this;
+ }
+
+ /**
+ * Sets the content description.
+ */
+ @NonNull
+ public Builder setContentDescription(
+ @Nullable CharSequence contentDescription) {
+ mContentDescription = contentDescription;
+ return this;
+ }
+
+ /**
+ * Sets the pending intent.
+ */
+ @NonNull
+ public Builder setPendingIntent(@Nullable PendingIntent pendingIntent) {
+ mPendingIntent = pendingIntent;
+ return this;
+ }
+
+ /**
+ * Sets the user handle.
+ */
+ @NonNull
+ public Builder setUserHandle(@Nullable UserHandle userHandle) {
+ mUserHandle = userHandle;
+ return this;
+ }
+
+ /**
+ * Sets the intent.
+ */
+ @NonNull
+ public Builder setIntent(@Nullable Intent intent) {
+ mIntent = intent;
+ return this;
+ }
+
+ /**
+ * Sets the extra.
+ */
+ @NonNull
+ public Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Builds a new SmartspaceAction instance.
+ *
+ * @throws IllegalStateException if no target is set
+ */
+ @NonNull
+ public SmartspaceAction build() {
+ return new SmartspaceAction(mId, mIcon, mTitle, mSubtitle, mContentDescription,
+ mPendingIntent, mIntent, mUserHandle, mExtras);
+ }
+ }
+}
diff --git a/core/java/android/app/smartspace/SmartspaceConfig.aidl b/core/java/android/app/smartspace/SmartspaceConfig.aidl
new file mode 100644
index 000000000000..136b6f412b54
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceConfig.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace;
+
+parcelable SmartspaceConfig; \ No newline at end of file
diff --git a/core/java/android/app/smartspace/SmartspaceConfig.java b/core/java/android/app/smartspace/SmartspaceConfig.java
new file mode 100644
index 000000000000..1f9cbb5ca33b
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceConfig.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app.smartspace;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * A {@link SmartspaceConfig} instance is supposed to be created by a smartspace client for each
+ * UISurface. The client can specify some initialization conditions for the UISurface like its name,
+ * expected number of smartspace cards etc. The clients can also specify if they want periodic
+ * updates or their desired maximum refresh frequency.
+ *
+ * @hide
+ */
+@SystemApi
+public final class SmartspaceConfig implements Parcelable {
+
+ /**
+ * The least number of smartspace targets expected to be predicted by the backend. The backend
+ * will always try to satisfy this threshold but it is not guaranteed to always meet it.
+ */
+ private final int mSmartspaceTargetCount;
+
+ /**
+ * A {@link mUiSurface} is the name of the surface which will be used to display the cards. A
+ * few examples are homescreen, lockscreen, aod etc.
+ */
+ @NonNull
+ private final String mUiSurface;
+
+ /** Package name of the client. */
+ @NonNull
+ private String mPackageName;
+
+ /** Send other client UI configurations in extras.
+ *
+ * This can include:
+ *
+ * - Desired maximum update frequency
+ * - Request to get periodic updates
+ * - Request to support multiple clients for the same UISurface.
+ */
+ @Nullable
+ private final Bundle mExtras;
+
+ private SmartspaceConfig(@NonNull String uiSurface, int numPredictedTargets,
+ @NonNull String packageName, @Nullable Bundle extras) {
+ mUiSurface = uiSurface;
+ mSmartspaceTargetCount = numPredictedTargets;
+ mPackageName = packageName;
+ mExtras = extras;
+ }
+
+ private SmartspaceConfig(Parcel parcel) {
+ mUiSurface = parcel.readString();
+ mSmartspaceTargetCount = parcel.readInt();
+ mPackageName = parcel.readString();
+ mExtras = parcel.readBundle();
+ }
+
+ /** Returns the package name of the prediction context. */
+ @NonNull
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /** Returns the number of smartspace targets requested by the user. */
+ @NonNull
+ public int getSmartspaceTargetCount() {
+ return mSmartspaceTargetCount;
+ }
+
+ /** Returns the UISurface requested by the client. */
+ @NonNull
+ public String getUiSurface() {
+ return mUiSurface;
+ }
+
+ @Nullable
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mUiSurface);
+ dest.writeInt(mSmartspaceTargetCount);
+ dest.writeString(mPackageName);
+ dest.writeBundle(mExtras);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SmartspaceConfig that = (SmartspaceConfig) o;
+ return mSmartspaceTargetCount == that.mSmartspaceTargetCount
+ && Objects.equals(mUiSurface, that.mUiSurface)
+ && Objects.equals(mPackageName, that.mPackageName)
+ && Objects.equals(mExtras, that.mExtras);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mSmartspaceTargetCount, mUiSurface, mPackageName, mExtras);
+ }
+
+ /**
+ * @see Creator
+ */
+ @NonNull
+ public static final Creator<SmartspaceConfig> CREATOR =
+ new Creator<SmartspaceConfig>() {
+ public SmartspaceConfig createFromParcel(Parcel parcel) {
+ return new SmartspaceConfig(parcel);
+ }
+
+ public SmartspaceConfig[] newArray(int size) {
+ return new SmartspaceConfig[size];
+ }
+ };
+
+ /**
+ * A builder for {@link SmartspaceConfig}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final class Builder {
+ @NonNull
+ private int mSmartspaceTargetCount = 5; // Default count is 5
+ @NonNull
+ private final String mUiSurface;
+ @NonNull
+ private final String mPackageName;
+ @NonNull
+ private Bundle mExtras = Bundle.EMPTY;
+
+ /**
+ * @param context The {@link Context} which is used to fetch the package name.
+ * @param uiSurface the UI Surface name associated with this context.
+ * @hide
+ */
+ @SystemApi
+ public Builder(@NonNull Context context, @NonNull String uiSurface) {
+ mPackageName = context.getPackageName();
+ this.mUiSurface = uiSurface;
+ }
+
+ /**
+ * Used to set the expected number of cards for this context.
+ */
+ @NonNull
+ public Builder setSmartspaceTargetCount(int smartspaceTargetCount) {
+ this.mSmartspaceTargetCount = smartspaceTargetCount;
+ return this;
+ }
+
+ /**
+ * Used to send a bundle containing extras for the {@link SmartspaceConfig}.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ this.mExtras = extras;
+ return this;
+ }
+
+ /**
+ * Returns an instance of {@link SmartspaceConfig}.
+ */
+ @NonNull
+ public SmartspaceConfig build() {
+ return new SmartspaceConfig(mUiSurface, mSmartspaceTargetCount, mPackageName, mExtras);
+ }
+ }
+}
diff --git a/core/java/android/app/smartspace/SmartspaceManager.java b/core/java/android/app/smartspace/SmartspaceManager.java
new file mode 100644
index 000000000000..ff5eb109dfe0
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceManager.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.content.Context;
+
+import java.util.Objects;
+
+/**
+ * Smartspace is a container in Android which is used to show contextual content powered by the
+ * intelligence service running on the device. A smartspace container can be on AoD, lockscreen or
+ * on the homescreen and can show personalized cards which are either derived from on device or
+ * online signals.
+ *
+ * {@link SmartspaceManager} is a system service that provides methods to create Smartspace session
+ * clients. An instance of this class is returned when a client calls
+ * <code> context.getSystemService("smartspace"); </code>.
+ *
+ * After receiving the service, a client must call
+ * {@link SmartspaceManager#createSmartspaceSession(SmartspaceConfig)} with a corresponding
+ * {@link SmartspaceConfig} to get an instance of {@link SmartspaceSession}.
+ * This session is then a client's point of contact with the api. They can send events, request for
+ * updates using the session. It is client's duty to call {@link SmartspaceSession#destroy()} to
+ * destroy the session once they no longer need it.
+ *
+ * @hide
+ */
+@SystemApi
+public final class SmartspaceManager {
+
+ private final Context mContext;
+
+ /**
+ * @hide
+ */
+ public SmartspaceManager(Context context) {
+ mContext = Objects.requireNonNull(context);
+ }
+
+ /**
+ * Creates a new Smartspace session.
+ */
+ @NonNull
+ public SmartspaceSession createSmartspaceSession(
+ @NonNull SmartspaceConfig smartspaceConfig) {
+ return new SmartspaceSession(mContext, smartspaceConfig);
+ }
+}
diff --git a/core/java/android/app/smartspace/SmartspaceSession.java b/core/java/android/app/smartspace/SmartspaceSession.java
new file mode 100644
index 000000000000..16def61239cf
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceSession.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app.smartspace;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.app.smartspace.ISmartspaceCallback.Stub;
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import dalvik.system.CloseGuard;
+
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+
+/**
+ * Client API to share information about the Smartspace UI state and execute query.
+ *
+ * <p>
+ * Usage: <pre> {@code
+ *
+ * class MyActivity {
+ * private SmartspaceSession mSmartspaceSession;
+ *
+ * void onCreate() {
+ * mSmartspaceSession = mSmartspaceManager.createSmartspaceSession(smartspaceConfig)
+ * mSmartspaceSession.registerSmartspaceUpdates(...)
+ * }
+ *
+ * void onStart() {
+ * mSmartspaceSession.requestSmartspaceUpdate()
+ * }
+ *
+ * void onTouch(...) OR
+ * void onStateTransitionStarted(...) OR
+ * void onResume(...) OR
+ * void onStop(...) {
+ * mSmartspaceSession.notifyEvent(event);
+ * }
+ *
+ * void onDestroy() {
+ * mSmartspaceSession.unregisterPredictionUpdates()
+ * mSmartspaceSession.destroy();
+ * }
+ *
+ * }</pre>
+ *
+ * @hide
+ */
+@SystemApi
+public final class SmartspaceSession implements AutoCloseable {
+
+ private static final String TAG = SmartspaceSession.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private final android.app.smartspace.ISmartspaceManager mInterface;
+ private final CloseGuard mCloseGuard = CloseGuard.get();
+ private final AtomicBoolean mIsClosed = new AtomicBoolean(false);
+
+ private final SmartspaceSessionId mSessionId;
+ private final ArrayMap<Callback, CallbackWrapper> mRegisteredCallbacks = new ArrayMap<>();
+ private final IBinder mToken = new Binder();
+
+ /**
+ * Creates a new Smartspace ui client.
+ * <p>
+ * The caller should call {@link SmartspaceSession#destroy()} to dispose the client once it
+ * no longer used.
+ *
+ * @param context the {@link Context} of the user of this {@link SmartspaceSession}.
+ * @param smartspaceConfig the Smartspace context.
+ */
+ // b/177858121 Create weak reference child objects to not leak context.
+ SmartspaceSession(@NonNull Context context, @NonNull SmartspaceConfig smartspaceConfig) {
+ IBinder b = ServiceManager.getService(Context.SMARTSPACE_SERVICE);
+ mInterface = android.app.smartspace.ISmartspaceManager.Stub.asInterface(b);
+ mSessionId = new SmartspaceSessionId(
+ context.getPackageName() + ":" + UUID.randomUUID().toString(), context.getUserId());
+ try {
+ mInterface.createSmartspaceSession(smartspaceConfig, mSessionId, mToken);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to cerate Smartspace session", e);
+ e.rethrowFromSystemServer();
+ }
+
+ mCloseGuard.open("close");
+ }
+
+ /**
+ * Notifies the Smartspace service of a Smartspace target event.
+ *
+ * @param event The {@link SmartspaceTargetEvent} that represents the Smartspace target event.
+ */
+ public void notifySmartspaceEvent(@NonNull SmartspaceTargetEvent event) {
+ if (mIsClosed.get()) {
+ throw new IllegalStateException("This client has already been destroyed.");
+ }
+ try {
+ mInterface.notifySmartspaceEvent(mSessionId, event);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to notify event", e);
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Requests the smartspace service for an update.
+ */
+ public void requestSmartspaceUpdate() {
+ if (mIsClosed.get()) {
+ throw new IllegalStateException("This client has already been destroyed.");
+ }
+ try {
+ mInterface.requestSmartspaceUpdate(mSessionId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to request update.", e);
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Requests the smartspace service provide continuous updates of smartspace cards via the
+ * provided callback, until the given callback is unregistered.
+ *
+ * @param callbackExecutor The callback executor to use when calling the callback.
+ * @param callback The Callback to be called when updates of Smartspace targets are
+ * available.
+ */
+ public void registerSmartspaceUpdates(@NonNull @CallbackExecutor Executor callbackExecutor,
+ @NonNull Callback callback) {
+ if (mIsClosed.get()) {
+ throw new IllegalStateException("This client has already been destroyed.");
+ }
+
+ if (mRegisteredCallbacks.containsKey(callback)) {
+ // Skip if this callback is already registered
+ return;
+ }
+ try {
+ final CallbackWrapper callbackWrapper = new CallbackWrapper(callbackExecutor,
+ callback::onTargetsAvailable);
+ mRegisteredCallbacks.put(callback, callbackWrapper);
+ mInterface.registerSmartspaceUpdates(mSessionId, callbackWrapper);
+ mInterface.requestSmartspaceUpdate(mSessionId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to register for smartspace updates", e);
+ e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
+ * Requests the smartspace service to stop providing continuous updates to the provided
+ * callback until the callback is re-registered.
+ *
+ * @see {@link SmartspaceSession#registerSmartspaceUpdates(Executor, Callback)}.
+ *
+ * @param callback The callback to be unregistered.
+ */
+ public void unregisterSmartspaceUpdates(@NonNull Callback callback) {
+ if (mIsClosed.get()) {
+ throw new IllegalStateException("This client has already been destroyed.");
+ }
+
+ if (!mRegisteredCallbacks.containsKey(callback)) {
+ // Skip if this callback was never registered
+ return;
+ }
+ try {
+ final CallbackWrapper callbackWrapper = mRegisteredCallbacks.remove(callback);
+ mInterface.unregisterSmartspaceUpdates(mSessionId, callbackWrapper);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to unregister for smartspace updates", e);
+ e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**
+ * Destroys the client and unregisters the callback. Any method on this class after this call
+ * will throw {@link IllegalStateException}.
+ */
+ public void destroy() {
+ if (!mIsClosed.getAndSet(true)) {
+ mCloseGuard.close();
+
+ // Do destroy;
+ try {
+ mInterface.destroySmartspaceSession(mSessionId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to notify Smartspace target event", e);
+ e.rethrowFromSystemServer();
+ }
+ } else {
+ throw new IllegalStateException("This client has already been destroyed.");
+ }
+ }
+
+ @Override
+ protected void finalize() {
+ try {
+ if (mCloseGuard != null) {
+ mCloseGuard.warnIfOpen();
+ }
+ if (!mIsClosed.get()) {
+ destroy();
+ }
+ } finally {
+ try {
+ super.finalize();
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public void close() {
+ try {
+ finalize();
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ }
+ }
+
+ /**
+ * Callback for receiving smartspace updates.
+ */
+ public interface Callback {
+
+ /**
+ * Called when a new set of smartspace targets are available.
+ *
+ * @param targets Sorted list of smartspace targets.
+ */
+ void onTargetsAvailable(@NonNull List<SmartspaceTarget> targets);
+ }
+
+ static class CallbackWrapper extends Stub {
+
+ private final Consumer<List<SmartspaceTarget>> mCallback;
+ private final Executor mExecutor;
+
+ CallbackWrapper(@NonNull Executor callbackExecutor,
+ @NonNull Consumer<List<SmartspaceTarget>> callback) {
+ mCallback = callback;
+ mExecutor = callbackExecutor;
+ }
+
+ @Override
+ public void onResult(ParceledListSlice result) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ if (DEBUG) {
+ Log.d(TAG, "CallbackWrapper.onResult result=" + result.getList());
+ }
+ mExecutor.execute(() -> mCallback.accept(result.getList()));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+}
diff --git a/core/java/android/app/smartspace/SmartspaceSessionId.aidl b/core/java/android/app/smartspace/SmartspaceSessionId.aidl
new file mode 100644
index 000000000000..a864412edd65
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceSessionId.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace;
+
+parcelable SmartspaceSessionId; \ No newline at end of file
diff --git a/core/java/android/app/smartspace/SmartspaceSessionId.java b/core/java/android/app/smartspace/SmartspaceSessionId.java
new file mode 100644
index 000000000000..5220c35d7064
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceSessionId.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * The id for an Smartspace session. See {@link SmartspaceSession}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class SmartspaceSessionId implements Parcelable {
+
+ @NonNull
+ private final String mId;
+
+ @NonNull
+ private final int mUserId;
+
+ /**
+ * Creates a new id for a Smartspace session.
+ *
+ * @hide
+ */
+ public SmartspaceSessionId(@NonNull final String id, @NonNull final int userId) {
+ mId = id;
+ mUserId = userId;
+ }
+
+ private SmartspaceSessionId(Parcel p) {
+ mId = p.readString();
+ mUserId = p.readInt();
+ }
+
+ /**
+ * Returns a {@link String} Id of this sessionId.
+ */
+ @Nullable
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Returns the userId associated with this sessionId.
+ */
+ @NonNull
+ public int getUserId() {
+ return mUserId;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (!getClass().equals(o != null ? o.getClass() : null)) return false;
+
+ SmartspaceSessionId other = (SmartspaceSessionId) o;
+ return mId.equals(other.mId) && mUserId == other.mUserId;
+ }
+
+ @Override
+ public String toString() {
+ return "SmartspaceSessionId{"
+ + "mId='" + mId + '\''
+ + ", mUserId=" + mUserId
+ + '}';
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId, mUserId);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mId);
+ dest.writeInt(mUserId);
+ }
+
+ public static final @NonNull Creator<SmartspaceSessionId> CREATOR =
+ new Creator<SmartspaceSessionId>() {
+ public SmartspaceSessionId createFromParcel(Parcel parcel) {
+ return new SmartspaceSessionId(parcel);
+ }
+
+ public SmartspaceSessionId[] newArray(int size) {
+ return new SmartspaceSessionId[size];
+ }
+ };
+}
diff --git a/core/java/android/app/smartspace/SmartspaceTarget.aidl b/core/java/android/app/smartspace/SmartspaceTarget.aidl
new file mode 100644
index 000000000000..3442cf294cbb
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceTarget.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace;
+
+parcelable SmartspaceTarget; \ No newline at end of file
diff --git a/core/java/android/app/smartspace/SmartspaceTarget.java b/core/java/android/app/smartspace/SmartspaceTarget.java
new file mode 100644
index 000000000000..ce5040eb0a3e
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceTarget.java
@@ -0,0 +1,660 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app.smartspace;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A {@link SmartspaceTarget} is a data class which holds all properties necessary to inflate a
+ * smartspace card. It contains data and related metadata which is supposed to be utilized by
+ * smartspace clients based on their own UI/UX requirements. Some of the properties have
+ * {@link SmartspaceAction} as their type because they can have associated actions.
+ *
+ * <p><b>NOTE: </b>
+ * If {@link mWidgetId} is set, it should be preferred over all other properties.
+ * Else, if {@link mSliceUri} is set, it should be preferred over all other data properties.
+ * Otherwise, the instance should be treated as a data object.
+ *
+ * @hide
+ */
+@SystemApi
+public final class SmartspaceTarget implements Parcelable {
+
+ /** A unique Id for an instance of {@link SmartspaceTarget}. */
+ @NonNull
+ private final String mSmartspaceTargetId;
+
+ /** A {@link SmartspaceAction} for the header in the Smartspace card. */
+ @Nullable
+ private final SmartspaceAction mHeaderAction;
+
+ /** A {@link SmartspaceAction} for the base action in the Smartspace card. */
+ @Nullable
+ private final SmartspaceAction mBaseAction;
+
+ /** A timestamp indicating when the card was created. */
+ @NonNull
+ private final long mCreationTimeMillis;
+
+ /**
+ * A timestamp indicating when the card should be removed from view, in case the service
+ * disconnects or restarts.
+ */
+ @NonNull
+ private final long mExpiryTimeMillis;
+
+ /** A score assigned to a target. */
+ @NonNull
+ private final float mScore;
+
+ /** A {@link List<SmartspaceAction>} containing all action chips. */
+ @NonNull
+ private final List<SmartspaceAction> mActionChips;
+
+ /** A {@link List<SmartspaceAction>} containing all icons for the grid. */
+ @NonNull
+ private final List<SmartspaceAction> mIconGrid;
+
+ /**
+ * {@link FeatureType} indicating the feature type of this card.
+ *
+ * @see FeatureType
+ */
+ @FeatureType
+ @NonNull
+ private final int mFeatureType;
+
+ /**
+ * Indicates whether the content is sensitive. Certain UI surfaces may choose to skip rendering
+ * real content until the device is unlocked.
+ */
+ @NonNull
+ private final boolean mSensitive;
+
+ /** Indicating if the UI should show this target in its expanded state. */
+ @NonNull
+ private final boolean mShouldShowExpanded;
+
+ /** A Notification key if the target was generated using a notification. */
+ @Nullable
+ private final String mSourceNotificationKey;
+
+ /** {@link ComponentName} for this target. */
+ @NonNull
+ private final ComponentName mComponentName;
+
+ /** {@link UserHandle} for this target. */
+ @NonNull
+ private final UserHandle mUserHandle;
+
+ /** Target Ids of other {@link SmartspaceTarget}s if they are associated with this target. */
+ @Nullable
+ private final String mAssociatedSmartspaceTargetId;
+
+ /** {@link Uri} Slice Uri if this target is a slice. */
+ @Nullable
+ private final Uri mSliceUri;
+
+ /** {@link AppWidgetProviderInfo} if this target is a widget. */
+ @Nullable
+ private final AppWidgetProviderInfo mWidgetId;
+
+ public static final int FEATURE_UNDEFINED = 0;
+ public static final int FEATURE_WEATHER = 1;
+ public static final int FEATURE_CALENDAR = 2;
+ public static final int FEATURE_COMMUTE_TIME = 3;
+ public static final int FEATURE_FLIGHT = 4;
+ public static final int FEATURE_TIPS = 5;
+ public static final int FEATURE_REMINDER = 6;
+ public static final int FEATURE_ALARM = 7;
+ public static final int FEATURE_ONBOARDING = 8;
+ public static final int FEATURE_SPORTS = 9;
+ public static final int FEATURE_WEATHER_ALERT = 10;
+ public static final int FEATURE_CONSENT = 11;
+ public static final int FEATURE_STOCK_PRICE_CHANGE = 12;
+ public static final int FEATURE_SHOPPING_LIST = 13;
+ public static final int FEATURE_LOYALTY_CARD = 14;
+ public static final int FEATURE_MEDIA = 15;
+ public static final int FEATURE_BEDTIME_ROUTINE = 16;
+ public static final int FEATURE_FITNESS_TRACKING = 17;
+ public static final int FEATURE_ETA_MONITORING = 18;
+ public static final int FEATURE_MISSED_CALL = 19;
+ public static final int FEATURE_PACKAGE_TRACKING = 20;
+ public static final int FEATURE_TIMER = 21;
+ public static final int FEATURE_STOPWATCH = 22;
+ public static final int FEATURE_UPCOMING_ALARM = 23;
+
+ /**
+ * @hide
+ */
+ @IntDef(prefix = {"FEATURE_"}, value = {
+ FEATURE_UNDEFINED,
+ FEATURE_WEATHER,
+ FEATURE_CALENDAR,
+ FEATURE_COMMUTE_TIME,
+ FEATURE_FLIGHT,
+ FEATURE_TIPS,
+ FEATURE_REMINDER,
+ FEATURE_ALARM,
+ FEATURE_ONBOARDING,
+ FEATURE_SPORTS,
+ FEATURE_WEATHER_ALERT,
+ FEATURE_CONSENT,
+ FEATURE_STOCK_PRICE_CHANGE,
+ FEATURE_SHOPPING_LIST,
+ FEATURE_LOYALTY_CARD,
+ FEATURE_MEDIA,
+ FEATURE_BEDTIME_ROUTINE,
+ FEATURE_FITNESS_TRACKING,
+ FEATURE_ETA_MONITORING,
+ FEATURE_MISSED_CALL,
+ FEATURE_PACKAGE_TRACKING,
+ FEATURE_TIMER,
+ FEATURE_STOPWATCH,
+ FEATURE_UPCOMING_ALARM
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FeatureType {
+ }
+
+ private SmartspaceTarget(Parcel in) {
+ this.mSmartspaceTargetId = in.readString();
+ this.mHeaderAction = in.readTypedObject(SmartspaceAction.CREATOR);
+ this.mBaseAction = in.readTypedObject(SmartspaceAction.CREATOR);
+ this.mCreationTimeMillis = in.readLong();
+ this.mExpiryTimeMillis = in.readLong();
+ this.mScore = in.readFloat();
+ this.mActionChips = in.createTypedArrayList(SmartspaceAction.CREATOR);
+ this.mIconGrid = in.createTypedArrayList(SmartspaceAction.CREATOR);
+ this.mFeatureType = in.readInt();
+ this.mSensitive = in.readBoolean();
+ this.mShouldShowExpanded = in.readBoolean();
+ this.mSourceNotificationKey = in.readString();
+ this.mComponentName = in.readTypedObject(ComponentName.CREATOR);
+ this.mUserHandle = in.readTypedObject(UserHandle.CREATOR);
+ this.mAssociatedSmartspaceTargetId = in.readString();
+ this.mSliceUri = in.readTypedObject(Uri.CREATOR);
+ this.mWidgetId = in.readTypedObject(AppWidgetProviderInfo.CREATOR);
+ }
+
+ private SmartspaceTarget(String smartspaceTargetId,
+ SmartspaceAction headerAction, SmartspaceAction baseAction, long creationTimeMillis,
+ long expiryTimeMillis, float score,
+ List<SmartspaceAction> actionChips,
+ List<SmartspaceAction> iconGrid, int featureType, boolean sensitive,
+ boolean shouldShowExpanded, String sourceNotificationKey,
+ ComponentName componentName, UserHandle userHandle,
+ String associatedSmartspaceTargetId, Uri sliceUri,
+ AppWidgetProviderInfo widgetId) {
+ mSmartspaceTargetId = smartspaceTargetId;
+ mHeaderAction = headerAction;
+ mBaseAction = baseAction;
+ mCreationTimeMillis = creationTimeMillis;
+ mExpiryTimeMillis = expiryTimeMillis;
+ mScore = score;
+ mActionChips = actionChips;
+ mIconGrid = iconGrid;
+ mFeatureType = featureType;
+ mSensitive = sensitive;
+ mShouldShowExpanded = shouldShowExpanded;
+ mSourceNotificationKey = sourceNotificationKey;
+ mComponentName = componentName;
+ mUserHandle = userHandle;
+ mAssociatedSmartspaceTargetId = associatedSmartspaceTargetId;
+ mSliceUri = sliceUri;
+ mWidgetId = widgetId;
+ }
+
+ /**
+ * Returns the Id of the target.
+ */
+ @NonNull
+ public String getSmartspaceTargetId() {
+ return mSmartspaceTargetId;
+ }
+
+ /**
+ * Returns the header action of the target.
+ */
+ @Nullable
+ public SmartspaceAction getHeaderAction() {
+ return mHeaderAction;
+ }
+
+ /**
+ * Returns the base action of the target.
+ */
+ @Nullable
+ public SmartspaceAction getBaseAction() {
+ return mBaseAction;
+ }
+
+ /**
+ * Returns the creation time of the target.
+ */
+ @NonNull
+ public long getCreationTimeMillis() {
+ return mCreationTimeMillis;
+ }
+
+ /**
+ * Returns the expiry time of the target.
+ */
+ @NonNull
+ public long getExpiryTimeMillis() {
+ return mExpiryTimeMillis;
+ }
+
+ /**
+ * Returns the score of the target.
+ */
+ @NonNull
+ public float getScore() {
+ return mScore;
+ }
+
+ /**
+ * Return the action chips of the target.
+ */
+ @NonNull
+ public List<SmartspaceAction> getActionChips() {
+ return mActionChips;
+ }
+
+ /**
+ * Return the icons of the target.
+ */
+ @NonNull
+ public List<SmartspaceAction> getIconGrid() {
+ return mIconGrid;
+ }
+
+ /**
+ * Returns the feature type of the target.
+ */
+ @NonNull
+ public int getFeatureType() {
+ return mFeatureType;
+ }
+
+ /**
+ * Returns whether the target is sensitive or not.
+ */
+ @NonNull
+ public boolean isSensitive() {
+ return mSensitive;
+ }
+
+ /**
+ * Returns whether the target should be shown in expanded state.
+ */
+ @NonNull
+ public boolean shouldShowExpanded() {
+ return mShouldShowExpanded;
+ }
+
+ /**
+ * Returns the source notification key of the target.
+ */
+ @Nullable
+ public String getSourceNotificationKey() {
+ return mSourceNotificationKey;
+ }
+
+ /**
+ * Returns the component name of the target.
+ */
+ @NonNull
+ public ComponentName getComponentName() {
+ return mComponentName;
+ }
+
+ /**
+ * Returns the user handle of the target.
+ */
+ @NonNull
+ public UserHandle getUserHandle() {
+ return mUserHandle;
+ }
+
+ /**
+ * Returns the id of a target associated with this instance.
+ */
+ @Nullable
+ public String getAssociatedSmartspaceTargetId() {
+ return mAssociatedSmartspaceTargetId;
+ }
+
+ /**
+ * Returns the slice uri, if the target is a slice.
+ */
+ @Nullable
+ public Uri getSliceUri() {
+ return mSliceUri;
+ }
+
+ /**
+ * Returns the AppWidgetProviderInfo, if the target is a widget.
+ */
+ @Nullable
+ public AppWidgetProviderInfo getWidgetId() {
+ return mWidgetId;
+ }
+
+ /**
+ * @see Parcelable.Creator
+ */
+ @NonNull
+ public static final Creator<SmartspaceTarget> CREATOR = new Creator<SmartspaceTarget>() {
+ @Override
+ public SmartspaceTarget createFromParcel(Parcel source) {
+ return new SmartspaceTarget(source);
+ }
+
+ @Override
+ public SmartspaceTarget[] newArray(int size) {
+ return new SmartspaceTarget[size];
+ }
+ };
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(this.mSmartspaceTargetId);
+ dest.writeTypedObject(this.mHeaderAction, flags);
+ dest.writeTypedObject(this.mBaseAction, flags);
+ dest.writeLong(this.mCreationTimeMillis);
+ dest.writeLong(this.mExpiryTimeMillis);
+ dest.writeFloat(this.mScore);
+ dest.writeTypedList(this.mActionChips);
+ dest.writeTypedList(this.mIconGrid);
+ dest.writeInt(this.mFeatureType);
+ dest.writeBoolean(this.mSensitive);
+ dest.writeBoolean(this.mShouldShowExpanded);
+ dest.writeString(this.mSourceNotificationKey);
+ dest.writeTypedObject(this.mComponentName, flags);
+ dest.writeTypedObject(this.mUserHandle, flags);
+ dest.writeString(this.mAssociatedSmartspaceTargetId);
+ dest.writeTypedObject(this.mSliceUri, flags);
+ dest.writeTypedObject(this.mWidgetId, flags);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ return "SmartspaceTarget{"
+ + "mSmartspaceTargetId='" + mSmartspaceTargetId + '\''
+ + ", mHeaderAction=" + mHeaderAction
+ + ", mBaseAction=" + mBaseAction
+ + ", mCreationTimeMillis=" + mCreationTimeMillis
+ + ", mExpiryTimeMillis=" + mExpiryTimeMillis
+ + ", mScore=" + mScore
+ + ", mActionChips=" + mActionChips
+ + ", mIconGrid=" + mIconGrid
+ + ", mFeatureType=" + mFeatureType
+ + ", mSensitive=" + mSensitive
+ + ", mShouldShowExpanded=" + mShouldShowExpanded
+ + ", mSourceNotificationKey='" + mSourceNotificationKey + '\''
+ + ", mComponentName=" + mComponentName
+ + ", mUserHandle=" + mUserHandle
+ + ", mAssociatedSmartspaceTargetId='" + mAssociatedSmartspaceTargetId + '\''
+ + ", mSliceUri=" + mSliceUri
+ + ", mWidgetId=" + mWidgetId
+ + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ SmartspaceTarget that = (SmartspaceTarget) o;
+ return mCreationTimeMillis == that.mCreationTimeMillis
+ && mExpiryTimeMillis == that.mExpiryTimeMillis
+ && Float.compare(that.mScore, mScore) == 0
+ && mFeatureType == that.mFeatureType
+ && mSensitive == that.mSensitive
+ && mShouldShowExpanded == that.mShouldShowExpanded
+ && mSmartspaceTargetId.equals(that.mSmartspaceTargetId)
+ && Objects.equals(mHeaderAction, that.mHeaderAction)
+ && Objects.equals(mBaseAction, that.mBaseAction)
+ && Objects.equals(mActionChips, that.mActionChips)
+ && Objects.equals(mIconGrid, that.mIconGrid)
+ && Objects.equals(mSourceNotificationKey, that.mSourceNotificationKey)
+ && mComponentName.equals(that.mComponentName)
+ && mUserHandle.equals(that.mUserHandle)
+ && Objects.equals(mAssociatedSmartspaceTargetId,
+ that.mAssociatedSmartspaceTargetId)
+ && Objects.equals(mSliceUri, that.mSliceUri)
+ && Objects.equals(mWidgetId, that.mWidgetId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mSmartspaceTargetId, mHeaderAction, mBaseAction, mCreationTimeMillis,
+ mExpiryTimeMillis, mScore, mActionChips, mIconGrid, mFeatureType, mSensitive,
+ mShouldShowExpanded, mSourceNotificationKey, mComponentName, mUserHandle,
+ mAssociatedSmartspaceTargetId, mSliceUri, mWidgetId);
+ }
+
+ /**
+ * A builder for {@link SmartspaceTarget} object.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final class Builder {
+ private final String mSmartspaceTargetId;
+ private SmartspaceAction mHeaderAction;
+ private SmartspaceAction mBaseAction;
+ private long mCreationTimeMillis;
+ private long mExpiryTimeMillis;
+ private float mScore;
+ private List<SmartspaceAction> mActionChips = new ArrayList<>();
+ private List<SmartspaceAction> mIconGrid = new ArrayList<>();
+ private int mFeatureType;
+ private boolean mSensitive;
+ private boolean mShouldShowExpanded;
+ private String mSourceNotificationKey;
+ private final ComponentName mComponentName;
+ private final UserHandle mUserHandle;
+ private String mAssociatedSmartspaceTargetId;
+ private Uri mSliceUri;
+ private AppWidgetProviderInfo mWidgetId;
+
+ /**
+ * A builder for {@link SmartspaceTarget}.
+ *
+ * @param smartspaceTargetId the id of this target
+ * @param componentName the componentName of this target
+ * @param userHandle the userHandle of this target
+ */
+ public Builder(@NonNull String smartspaceTargetId,
+ @NonNull ComponentName componentName, @NonNull UserHandle userHandle) {
+ this.mSmartspaceTargetId = smartspaceTargetId;
+ this.mComponentName = componentName;
+ this.mUserHandle = userHandle;
+ }
+
+ /**
+ * Sets the header action.
+ */
+ @NonNull
+ public Builder setHeaderAction(@NonNull SmartspaceAction headerAction) {
+ this.mHeaderAction = headerAction;
+ return this;
+ }
+
+ /**
+ * Sets the base action.
+ */
+ @NonNull
+ public Builder setBaseAction(@NonNull SmartspaceAction baseAction) {
+ this.mBaseAction = baseAction;
+ return this;
+ }
+
+ /**
+ * Sets the creation time.
+ */
+ @NonNull
+ public Builder setCreationTimeMillis(@NonNull long creationTimeMillis) {
+ this.mCreationTimeMillis = creationTimeMillis;
+ return this;
+ }
+
+ /**
+ * Sets the expiration time.
+ */
+ @NonNull
+ public Builder setExpiryTimeMillis(@NonNull long expiryTimeMillis) {
+ this.mExpiryTimeMillis = expiryTimeMillis;
+ return this;
+ }
+
+ /**
+ * Sets the score.
+ */
+ @NonNull
+ public Builder setScore(@NonNull float score) {
+ this.mScore = score;
+ return this;
+ }
+
+ /**
+ * Sets the action chips.
+ */
+ @NonNull
+ public Builder setActionChips(@NonNull List<SmartspaceAction> actionChips) {
+ this.mActionChips = actionChips;
+ return this;
+ }
+
+ /**
+ * Sets the icon grid.
+ */
+ @NonNull
+ public Builder setIconGrid(@NonNull List<SmartspaceAction> iconGrid) {
+ this.mIconGrid = iconGrid;
+ return this;
+ }
+
+ /**
+ * Sets the feature type.
+ */
+ @NonNull
+ public Builder setFeatureType(@NonNull int featureType) {
+ this.mFeatureType = featureType;
+ return this;
+ }
+
+ /**
+ * Sets whether the contents are sensitive.
+ */
+ @NonNull
+ public Builder setSensitive(@NonNull boolean sensitive) {
+ this.mSensitive = sensitive;
+ return this;
+ }
+
+ /**
+ * Sets whether to show the card as expanded.
+ */
+ @NonNull
+ public Builder setShouldShowExpanded(@NonNull boolean shouldShowExpanded) {
+ this.mShouldShowExpanded = shouldShowExpanded;
+ return this;
+ }
+
+ /**
+ * Sets the source notification key.
+ */
+ @NonNull
+ public Builder setSourceNotificationKey(@NonNull String sourceNotificationKey) {
+ this.mSourceNotificationKey = sourceNotificationKey;
+ return this;
+ }
+
+ /**
+ * Sets the associated smartspace target id.
+ */
+ @NonNull
+ public Builder setAssociatedSmartspaceTargetId(
+ @NonNull String associatedSmartspaceTargetId) {
+ this.mAssociatedSmartspaceTargetId = associatedSmartspaceTargetId;
+ return this;
+ }
+
+ /**
+ * Sets the slice uri.
+ *
+ * <p><b>NOTE: </b> If {@link mWidgetId} is also set, {@link mSliceUri} should be ignored.
+ */
+ @NonNull
+ public Builder setSliceUri(@NonNull Uri sliceUri) {
+ this.mSliceUri = sliceUri;
+ return this;
+ }
+
+ /**
+ * Sets the widget id.
+ *
+ * <p><b>NOTE: </b> If {@link mWidgetId} is set, all other @Nullable params should be
+ * ignored.
+ */
+ @NonNull
+ public Builder setWidgetId(@NonNull AppWidgetProviderInfo widgetId) {
+ this.mWidgetId = widgetId;
+ return this;
+ }
+
+ /**
+ * Builds a new {@link SmartspaceTarget}.
+ *
+ * @throws IllegalStateException when non null fields are set as null.
+ */
+ @NonNull
+ public SmartspaceTarget build() {
+ if (mSmartspaceTargetId == null
+ || mComponentName == null
+ || mUserHandle == null) {
+ throw new IllegalStateException("Please assign a value to all @NonNull args.");
+ }
+ return new SmartspaceTarget(mSmartspaceTargetId,
+ mHeaderAction, mBaseAction, mCreationTimeMillis, mExpiryTimeMillis, mScore,
+ mActionChips, mIconGrid, mFeatureType, mSensitive, mShouldShowExpanded,
+ mSourceNotificationKey, mComponentName, mUserHandle,
+ mAssociatedSmartspaceTargetId, mSliceUri, mWidgetId);
+ }
+ }
+}
diff --git a/core/java/android/app/smartspace/SmartspaceTargetEvent.aidl b/core/java/android/app/smartspace/SmartspaceTargetEvent.aidl
new file mode 100644
index 000000000000..e797a9b7e42c
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceTargetEvent.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2021, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.smartspace;
+
+parcelable SmartspaceTargetEvent;
diff --git a/core/java/android/app/smartspace/SmartspaceTargetEvent.java b/core/java/android/app/smartspace/SmartspaceTargetEvent.java
new file mode 100644
index 000000000000..1e0653d67ace
--- /dev/null
+++ b/core/java/android/app/smartspace/SmartspaceTargetEvent.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app.smartspace;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A representation of a smartspace event.
+ *
+ * @hide
+ */
+@SystemApi
+public final class SmartspaceTargetEvent implements Parcelable {
+
+ /**
+ * User interacted with the target.
+ */
+ public static final int EVENT_TARGET_INTERACTION = 1;
+
+ /**
+ * Smartspace target was brought into view.
+ */
+ public static final int EVENT_TARGET_IN_VIEW = 2;
+ /**
+ * Smartspace target went out of view.
+ */
+ public static final int EVENT_TARGET_OUT_OF_VIEW = 3;
+ /**
+ * A dismiss action was issued by the user.
+ */
+ public static final int EVENT_TARGET_DISMISS = 4;
+ /**
+ * A block action was issued by the user.
+ */
+ public static final int EVENT_TARGET_BLOCK = 5;
+ /**
+ * The Ui surface came into view.
+ */
+ public static final int EVENT_UI_SURFACE_IN_VIEW = 6;
+ /**
+ * The Ui surface went out of view.
+ */
+ public static final int EVENT_UI_SURFACE_OUT_OF_VIEW = 7;
+
+ /**
+ * @see Parcelable.Creator
+ */
+ @NonNull
+ public static final Creator<SmartspaceTargetEvent> CREATOR =
+ new Creator<SmartspaceTargetEvent>() {
+ public SmartspaceTargetEvent createFromParcel(Parcel parcel) {
+ return new SmartspaceTargetEvent(parcel);
+ }
+
+ public SmartspaceTargetEvent[] newArray(int size) {
+ return new SmartspaceTargetEvent[size];
+ }
+ };
+
+ @Nullable
+ private final SmartspaceTarget mSmartspaceTarget;
+
+ @Nullable
+ private final String mSmartspaceActionId;
+
+ @EventType
+ private final int mEventType;
+
+ private SmartspaceTargetEvent(@Nullable SmartspaceTarget smartspaceTarget,
+ @Nullable String smartspaceActionId,
+ @EventType int eventType) {
+ mSmartspaceTarget = smartspaceTarget;
+ mSmartspaceActionId = smartspaceActionId;
+ mEventType = eventType;
+ }
+
+ private SmartspaceTargetEvent(Parcel parcel) {
+ mSmartspaceTarget = parcel.readParcelable(null);
+ mSmartspaceActionId = parcel.readString();
+ mEventType = parcel.readInt();
+ }
+
+ /**
+ * Get the {@link SmartspaceTarget} associated with this event.
+ */
+ @Nullable
+ public SmartspaceTarget getSmartspaceTarget() {
+ return mSmartspaceTarget;
+ }
+
+ /**
+ * Get the action id of the Smartspace Action associated with this event.
+ */
+ @Nullable
+ public String getSmartspaceActionId() {
+ return mSmartspaceActionId;
+ }
+
+ /**
+ * Get the {@link EventType} of this event.
+ */
+ @NonNull
+ @EventType
+ public int getEventType() {
+ return mEventType;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeParcelable(mSmartspaceTarget, flags);
+ dest.writeString(mSmartspaceActionId);
+ dest.writeInt(mEventType);
+ }
+
+ /**
+ * @hide
+ */
+ @IntDef(prefix = {"EVENT_"}, value = {
+ EVENT_TARGET_INTERACTION,
+ EVENT_TARGET_IN_VIEW,
+ EVENT_TARGET_OUT_OF_VIEW,
+ EVENT_TARGET_DISMISS,
+ EVENT_TARGET_BLOCK,
+ EVENT_UI_SURFACE_IN_VIEW,
+ EVENT_UI_SURFACE_OUT_OF_VIEW
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface EventType {
+ }
+
+ /**
+ * A builder for {@link SmartspaceTargetEvent}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final class Builder {
+ @EventType
+ private final int mEventType;
+ @Nullable
+ private SmartspaceTarget mSmartspaceTarget;
+ @Nullable
+ private String mSmartspaceActionId;
+
+ /**
+ * A builder for {@link SmartspaceTargetEvent}.
+ */
+ public Builder(@EventType int eventType) {
+ mEventType = eventType;
+ }
+
+ /**
+ * Sets the SmartspaceTarget for this event.
+ */
+ @NonNull
+ public Builder setSmartspaceTarget(@NonNull SmartspaceTarget smartspaceTarget) {
+ mSmartspaceTarget = smartspaceTarget;
+ return this;
+ }
+
+ /**
+ * Sets the Smartspace action id for this event.
+ */
+ @NonNull
+ public Builder setSmartspaceActionId(@NonNull String smartspaceActionId) {
+ mSmartspaceActionId = smartspaceActionId;
+ return this;
+ }
+
+ /**
+ * Builds a new {@link SmartspaceTargetEvent} instance.
+ */
+ @NonNull
+ public SmartspaceTargetEvent build() {
+ return new SmartspaceTargetEvent(mSmartspaceTarget, mSmartspaceActionId, mEventType);
+ }
+ }
+}
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 93d96d074db8..e96e22c4764a 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -406,6 +406,14 @@ public class AppWidgetProviderInfo implements Parcelable {
return new UserHandle(UserHandle.getUserId(providerInfo.applicationInfo.uid));
}
+ /**
+ * Returns the broadcast receiver that is providing this widget.
+ */
+ @NonNull
+ public ActivityInfo getProviderInfo() {
+ return providerInfo;
+ }
+
@Override
@SuppressWarnings("deprecation")
public void writeToParcel(Parcel out, int flags) {
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index d6b38fd32e8f..4fb557780d04 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -80,7 +80,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
/**
* Intent used to broadcast the change in the Audio Connection state of the
- * HDP profile.
+ * HFP profile.
*
* <p>This intent will have 3 extras:
* <ul>
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6a2329e5235f..6d42703f2730 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4371,6 +4371,16 @@ public abstract class Context {
public static final String BIOMETRIC_SERVICE = "biometric";
/**
+ * Use with {@link #getSystemService(String)} to retrieve a
+ * {@link android.media.MediaCommunicationManager}
+ * for managing {@link android.media.MediaSession2}.
+ *
+ * @see #getSystemService(String)
+ * @see android.media.MediaCommunicationManager
+ */
+ public static final String MEDIA_COMMUNICATION_SERVICE = "media_communication";
+
+ /**
* Use with {@link #getSystemService} to retrieve a
* {@link android.media.MediaRouter} for controlling and managing
* routing of media.
@@ -4615,6 +4625,18 @@ public abstract class Context {
public static final String SEARCH_UI_SERVICE = "search_ui";
/**
+ * Used for getting the smartspace service.
+ *
+ * <p><b>NOTE: </b> this service is optional; callers of
+ * {@code Context.getSystemServiceName(SMARTSPACE_SERVICE)} should check for {@code null}.
+ *
+ * @hide
+ * @see #getSystemService(String)
+ */
+ @SystemApi
+ public static final String SMARTSPACE_SERVICE = "smartspace";
+
+ /**
* Use with {@link #getSystemService(String)} to access the
* {@link com.android.server.voiceinteraction.SoundTriggerService}.
*
@@ -6144,6 +6166,7 @@ public abstract class Context {
@UiContext
@NonNull
public Context createWindowContext(@NonNull Display display, @WindowType int type,
+ @SuppressLint("NullableCollection")
@Nullable Bundle options) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index 82d7b6361738..16e720e3794c 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -17,6 +17,7 @@
package android.content.pm;
import android.annotation.FloatRange;
+import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -32,8 +33,6 @@ import android.util.DisplayMetrics;
* and badged icon for the activity.
*/
public class LauncherActivityInfo {
- private static final String TAG = "LauncherActivityInfo";
-
private final PackageManager mPm;
private UserHandle mUser;
private final LauncherActivityInfoInternal mInternal;
@@ -81,7 +80,7 @@ public class LauncherActivityInfo {
*/
public CharSequence getLabel() {
// TODO: Go through LauncherAppsService
- return mInternal.getActivityInfo().loadLabel(mPm);
+ return getActivityInfo().loadLabel(mPm);
}
/**
@@ -101,20 +100,20 @@ public class LauncherActivityInfo {
*/
public Drawable getIcon(int density) {
// TODO: Go through LauncherAppsService
- final int iconRes = mInternal.getActivityInfo().getIconResource();
+ final int iconRes = getActivityInfo().getIconResource();
Drawable icon = null;
// Get the preferred density icon from the app's resources
if (density != 0 && iconRes != 0) {
try {
final Resources resources = mPm.getResourcesForApplication(
- mInternal.getActivityInfo().applicationInfo);
+ getActivityInfo().applicationInfo);
icon = resources.getDrawableForDensity(iconRes, density);
} catch (NameNotFoundException | Resources.NotFoundException exc) {
}
}
// Get the default density icon
if (icon == null) {
- icon = mInternal.getActivityInfo().loadIcon(mPm);
+ icon = getActivityInfo().loadIcon(mPm);
}
return icon;
}
@@ -126,25 +125,25 @@ public class LauncherActivityInfo {
* @hide remove before shipping
*/
public int getApplicationFlags() {
- return mInternal.getActivityInfo().flags;
+ return getActivityInfo().flags;
}
/**
* Returns the ActivityInfo of the activity.
*
* @return Activity Info
- * @hide
*/
+ @NonNull
public ActivityInfo getActivityInfo() {
return mInternal.getActivityInfo();
}
/**
- * Returns the application info for the appliction this activity belongs to.
+ * Returns the application info for the application this activity belongs to.
* @return
*/
public ApplicationInfo getApplicationInfo() {
- return mInternal.getActivityInfo().applicationInfo;
+ return getActivityInfo().applicationInfo;
}
/**
@@ -155,7 +154,7 @@ public class LauncherActivityInfo {
public long getFirstInstallTime() {
try {
// TODO: Go through LauncherAppsService
- return mPm.getPackageInfo(mInternal.getActivityInfo().packageName,
+ return mPm.getPackageInfo(getActivityInfo().packageName,
PackageManager.MATCH_UNINSTALLED_PACKAGES).firstInstallTime;
} catch (NameNotFoundException nnfe) {
// Sorry, can't find package
@@ -164,11 +163,11 @@ public class LauncherActivityInfo {
}
/**
- * Returns the name for the acitivty from android:name in the manifest.
- * @return the name from android:name for the acitivity.
+ * Returns the name for the activity from android:name in the manifest.
+ * @return the name from android:name for the activity.
*/
public String getName() {
- return mInternal.getActivityInfo().name;
+ return getActivityInfo().name;
}
/**
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index f9913067d238..e8ef077fedc8 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -222,7 +222,7 @@ public class PackageInfo implements Parcelable {
* &lt;attribution&gt;} tags included under &lt;manifest&gt;, or null if there were none. This
* is only filled if the flag {@link PackageManager#GET_ATTRIBUTIONS} was set.
*/
- @SuppressWarnings("ArrayReturn")
+ @SuppressWarnings({"ArrayReturn", "NullableCollection"})
public @Nullable Attribution[] attributions;
/**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 9ae9c25c8c08..9085ed2be8b1 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -54,6 +54,7 @@ import android.content.pm.parsing.ParsingPackageUtils;
import android.content.pm.parsing.result.ParseInput;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.Rect;
@@ -6703,6 +6704,22 @@ public abstract class PackageManager {
throws NameNotFoundException;
/**
+ * Retrieve the resources for an application for the provided configuration.
+ *
+ * @param app Information about the desired application.
+ * @param configuration Overridden configuration when loading the Resources
+ *
+ * @return Returns the application's Resources.
+ * @throws NameNotFoundException Thrown if the resources for the given
+ * application could not be loaded (most likely because it was uninstalled).
+ */
+ @NonNull
+ public Resources getResourcesForApplication(@NonNull ApplicationInfo app, @Nullable
+ Configuration configuration) throws NameNotFoundException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* Retrieve the resources associated with an application. Given the full
* package name of an application, retrieves the information about it and
* calls getResources() to return its application's resources. If the
diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java
index 02fb06b808a2..bce4b872b8a6 100644
--- a/core/java/android/content/pm/Signature.java
+++ b/core/java/android/content/pm/Signature.java
@@ -256,6 +256,8 @@ public class Signature implements Parcelable {
try {
if (obj != null) {
Signature other = (Signature)obj;
+ // Note, some classes, such as PackageParser.SigningDetails, rely on equals
+ // only comparing the mSignature arrays without the flags.
return this == other || Arrays.equals(mSignature, other.mSignature);
}
} catch (ClassCastException e) {
@@ -268,6 +270,8 @@ public class Signature implements Parcelable {
if (mHaveHashCode) {
return mHashCode;
}
+ // Note, similar to equals some classes rely on the hash code not including
+ // the flags for Set membership checks.
mHashCode = Arrays.hashCode(mSignature);
mHaveHashCode = true;
return mHashCode;
diff --git a/core/java/android/hardware/Battery.java b/core/java/android/hardware/Battery.java
new file mode 100644
index 000000000000..24c8d76a9813
--- /dev/null
+++ b/core/java/android/hardware/Battery.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2021 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;
+
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.os.BatteryManager;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * The Battery class is a representation of a single battery on a device.
+ */
+public abstract class Battery {
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "STATUS_" }, value = {
+ STATUS_UNKNOWN,
+ STATUS_CHARGING,
+ STATUS_DISCHARGING,
+ STATUS_NOT_CHARGING,
+ STATUS_FULL
+ })
+ public @interface BatteryStatus {
+ }
+
+ /** Battery status is unknown. */
+ public static final int STATUS_UNKNOWN = BatteryManager.BATTERY_STATUS_UNKNOWN;
+ /** Battery is charging. */
+ public static final int STATUS_CHARGING = BatteryManager.BATTERY_STATUS_CHARGING;
+ /** Battery is discharging. */
+ public static final int STATUS_DISCHARGING = BatteryManager.BATTERY_STATUS_DISCHARGING;
+ /** Battery is connected to power but not charging. */
+ public static final int STATUS_NOT_CHARGING = BatteryManager.BATTERY_STATUS_NOT_CHARGING;
+ /** Battery is full. */
+ public static final int STATUS_FULL = BatteryManager.BATTERY_STATUS_FULL;
+
+ /**
+ * Check whether the hardware has a battery.
+ *
+ * @return True if the hardware has a battery, else false.
+ */
+ public abstract boolean hasBattery();
+
+ /**
+ * Get the battery status.
+ *
+ * @return the battery status.
+ */
+ public abstract @BatteryStatus int getStatus();
+
+ /**
+ * Get remaining battery capacity as float percentage [0.0f, 1.0f] of total capacity
+ * Returns -1 when battery capacity can't be read.
+ *
+ * @return the battery capacity.
+ */
+ public abstract @FloatRange(from = -1.0f, to = 1.0f) float getCapacity();
+}
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index b39df4d2b6bf..c69c47f80d01 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -93,6 +93,10 @@ interface IInputManager {
int[] getVibratorIds(int deviceId);
boolean isVibrating(int deviceId);
+ // Input device battery query.
+ int getBatteryStatus(int deviceId);
+ int getBatteryCapacity(int deviceId);
+
void setPointerIconType(int typeId);
void setCustomPointerIcon(in PointerIcon icon);
diff --git a/core/java/android/hardware/input/InputDeviceBattery.java b/core/java/android/hardware/input/InputDeviceBattery.java
new file mode 100644
index 000000000000..0fe124e2c0ce
--- /dev/null
+++ b/core/java/android/hardware/input/InputDeviceBattery.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 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.input;
+
+import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
+import static android.os.IInputConstants.INVALID_BATTERY_CAPACITY;
+
+import android.hardware.Battery;
+
+/**
+ * Battery implementation for input devices.
+ *
+ * @hide
+ */
+public final class InputDeviceBattery extends Battery {
+ private static final float NULL_BATTERY_CAPACITY = -1.0f;
+
+ private final InputManager mInputManager;
+ private final int mDeviceId;
+ private final boolean mHasBattery;
+
+ InputDeviceBattery(InputManager inputManager, int deviceId, boolean hasBattery) {
+ mInputManager = inputManager;
+ mDeviceId = deviceId;
+ mHasBattery = hasBattery;
+ }
+
+ @Override
+ public boolean hasBattery() {
+ return mHasBattery;
+ }
+
+ @Override
+ public int getStatus() {
+ if (!mHasBattery) {
+ return BATTERY_STATUS_UNKNOWN;
+ }
+ return mInputManager.getBatteryStatus(mDeviceId);
+ }
+
+ @Override
+ public float getCapacity() {
+ if (mHasBattery) {
+ int capacity = mInputManager.getBatteryCapacity(mDeviceId);
+ if (capacity != INVALID_BATTERY_CAPACITY) {
+ return (float) capacity / 100.0f;
+ }
+ }
+ return NULL_BATTERY_CAPACITY;
+ }
+}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 6ab11068aac7..185c59d8ccfc 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -25,6 +25,7 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.app.ActivityThread;
import android.compat.annotation.ChangeId;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -909,18 +910,17 @@ public final class InputManager {
}
/**
- * Returns the maximum allowed obscuring opacity by UID to propagate touches.
+ * Returns the maximum allowed obscuring opacity per UID to propagate touches.
*
- * For certain window types (eg. SAWs), the decision of honoring {@link LayoutParams
- * #FLAG_NOT_TOUCHABLE} or not depends on the combined obscuring opacity of the windows
- * above the touch-consuming window.
- *
- * @see #setMaximumObscuringOpacityForTouch(Context, float)
+ * <p>For certain window types (eg. {@link LayoutParams#TYPE_APPLICATION_OVERLAY}), the decision
+ * of honoring {@link LayoutParams#FLAG_NOT_TOUCHABLE} or not depends on the combined obscuring
+ * opacity of the windows above the touch-consuming window, per UID. Check documentation of
+ * {@link LayoutParams#FLAG_NOT_TOUCHABLE} for more details.
*
- * @hide
+ * @see LayoutParams#FLAG_NOT_TOUCHABLE
*/
- @TestApi
- public float getMaximumObscuringOpacityForTouch(@NonNull Context context) {
+ public float getMaximumObscuringOpacityForTouch() {
+ Context context = ActivityThread.currentApplication();
return Settings.Global.getFloat(context.getContentResolver(),
Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH,
DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH);
@@ -946,17 +946,18 @@ public final class InputManager {
*
* This value should be between 0 (inclusive) and 1 (inclusive).
*
- * @see #getMaximumObscuringOpacityForTouch(Context)
+ * @see #getMaximumObscuringOpacityForTouch()
*
* @hide
*/
@TestApi
@RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- public void setMaximumObscuringOpacityForTouch(@NonNull Context context, float opacity) {
+ public void setMaximumObscuringOpacityForTouch(float opacity) {
if (opacity < 0 || opacity > 1) {
throw new IllegalArgumentException(
"Maximum obscuring opacity for touch should be >= 0 and <= 1");
}
+ Context context = ActivityThread.currentApplication();
Settings.Global.putFloat(context.getContentResolver(),
Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH, opacity);
}
@@ -1244,6 +1245,32 @@ public final class InputManager {
}
/**
+ * Get the battery status of the input device
+ * @param deviceId The input device ID
+ * @hide
+ */
+ public int getBatteryStatus(int deviceId) {
+ try {
+ return mIm.getBatteryStatus(deviceId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get the remaining battery capacity of the input device
+ * @param deviceId The input device ID
+ * @hide
+ */
+ public int getBatteryCapacity(int deviceId) {
+ try {
+ return mIm.getBatteryCapacity(deviceId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Add a runtime association between the input port and the display port. This overrides any
* static associations.
* @param inputPort The port of the input device.
@@ -1470,6 +1497,15 @@ public final class InputManager {
}
/**
+ * Gets a battery object associated with an input device, assuming it has one.
+ * @return The battery, never null.
+ * @hide
+ */
+ public InputDeviceBattery getInputDeviceBattery(int deviceId, boolean hasBattery) {
+ return new InputDeviceBattery(this, deviceId, hasBattery);
+ }
+
+ /**
* Listens for changes in input devices.
*/
public interface InputDeviceListener {
diff --git a/core/java/android/hardware/location/ContextHubClientCallback.java b/core/java/android/hardware/location/ContextHubClientCallback.java
index 20fa7538e2d5..b31b85fdabf6 100644
--- a/core/java/android/hardware/location/ContextHubClientCallback.java
+++ b/core/java/android/hardware/location/ContextHubClientCallback.java
@@ -15,6 +15,7 @@
*/
package android.hardware.location;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import java.util.concurrent.Executor;
@@ -101,4 +102,34 @@ public class ContextHubClientCallback {
* @param nanoAppId the ID of the nanoapp that had been disabled
*/
public void onNanoAppDisabled(ContextHubClient client, long nanoAppId) {}
+
+ /**
+ * Callback invoked when a {@link ContextHubClient}'s authorization to communicate with a
+ * nanoapp changes. This typically happens as a result of the app that created the
+ * {@link ContextHubClient} gaining or losing the permissions required to communicate with a
+ * nanoapp.
+ *
+ * An example of the connection callbacks looks like:
+ * 1) {@link ContextHubClient} sends message to nanoapp and holds required permissions
+ * 2) {@link ContextHubClient} loses required permissions
+ * 3) Callback invoked with the nanoapp ID and
+ * {@link ContextHubManager#AUTHORIZATION_DENIED_GRACE_PERIOD}
+ * 4) {@link ContextHubClient} performs any cleanup required with the nanoapp
+ * 5) Callback invoked with the nanoapp ID and {@link ContextHubManager#AUTHORIZATION_DENIED}.
+ * At this point, any further attempts of communication between the nanoapp and the
+ * {@link ContextHubClient} will be dropped by the contexthub along with
+ * {@link ContextHubManager#AUTHORIZATION_DENIED} being sent. The {@link ContextHubClient}
+ * should assume no communciation can happen again until
+ * {@link ContextHubManager#AUTHORIZATION_GRANTED} is received.
+ *
+ * @param client the client that is associated with this callback
+ * @param nanoAppId the ID of the nanoapp associated with the new
+ * authorization state
+ * @param authorization the authorization state denoting the ability of the
+ * client to communicate with the nanoapp
+ */
+ public void onClientAuthorizationChanged(
+ @NonNull ContextHubClient client,
+ long nanoAppId,
+ @ContextHubManager.AuthorizationState int authorization) {}
}
diff --git a/core/java/android/hardware/location/ContextHubIntentEvent.java b/core/java/android/hardware/location/ContextHubIntentEvent.java
index 917f62bc6cbf..3e8f4219a485 100644
--- a/core/java/android/hardware/location/ContextHubIntentEvent.java
+++ b/core/java/android/hardware/location/ContextHubIntentEvent.java
@@ -43,39 +43,45 @@ public class ContextHubIntentEvent {
private final int mNanoAppAbortCode;
+ private final int mClientAuthorizationState;
+
private ContextHubIntentEvent(
@NonNull ContextHubInfo contextHubInfo, @ContextHubManager.Event int eventType,
- long nanoAppId, NanoAppMessage nanoAppMessage, int nanoAppAbortCode) {
+ long nanoAppId, NanoAppMessage nanoAppMessage, int nanoAppAbortCode,
+ @ContextHubManager.AuthorizationState int clientAuthorizationState) {
mContextHubInfo = contextHubInfo;
mEventType = eventType;
mNanoAppId = nanoAppId;
mNanoAppMessage = nanoAppMessage;
mNanoAppAbortCode = nanoAppAbortCode;
+ mClientAuthorizationState = clientAuthorizationState;
}
private ContextHubIntentEvent(
@NonNull ContextHubInfo contextHubInfo, @ContextHubManager.Event int eventType) {
this(contextHubInfo, eventType, -1 /* nanoAppId */, null /* nanoAppMessage */,
- -1 /* nanoAppAbortCode */);
+ -1 /* nanoAppAbortCode */, 0 /* clientAuthorizationState */);
}
private ContextHubIntentEvent(
@NonNull ContextHubInfo contextHubInfo, @ContextHubManager.Event int eventType,
long nanoAppId) {
this(contextHubInfo, eventType, nanoAppId, null /* nanoAppMessage */,
- -1 /* nanoAppAbortCode */);
+ -1 /* nanoAppAbortCode */, 0 /* clientAuthorizationState */);
}
private ContextHubIntentEvent(
@NonNull ContextHubInfo contextHubInfo, @ContextHubManager.Event int eventType,
long nanoAppId, @NonNull NanoAppMessage nanoAppMessage) {
- this(contextHubInfo, eventType, nanoAppId, nanoAppMessage, -1 /* nanoAppAbortCode */);
+ this(contextHubInfo, eventType, nanoAppId, nanoAppMessage, -1 /* nanoAppAbortCode */,
+ 0 /* clientAuthorizationState */);
}
private ContextHubIntentEvent(
@NonNull ContextHubInfo contextHubInfo, @ContextHubManager.Event int eventType,
long nanoAppId, int nanoAppAbortCode) {
- this(contextHubInfo, eventType, nanoAppId, null /* nanoAppMessage */, nanoAppAbortCode);
+ this(contextHubInfo, eventType, nanoAppId, null /* nanoAppMessage */, nanoAppAbortCode,
+ 0 /* clientAuthorizationState */);
}
/**
@@ -105,7 +111,8 @@ public class ContextHubIntentEvent {
case ContextHubManager.EVENT_NANOAPP_ENABLED:
case ContextHubManager.EVENT_NANOAPP_DISABLED:
case ContextHubManager.EVENT_NANOAPP_ABORTED:
- case ContextHubManager.EVENT_NANOAPP_MESSAGE: // fall through
+ case ContextHubManager.EVENT_NANOAPP_MESSAGE:
+ case ContextHubManager.EVENT_CLIENT_AUTHORIZATION: // fall through
long nanoAppId = getLongExtraOrThrow(intent, ContextHubManager.EXTRA_NANOAPP_ID);
if (eventType == ContextHubManager.EVENT_NANOAPP_MESSAGE) {
hasExtraOrThrow(intent, ContextHubManager.EXTRA_MESSAGE);
@@ -120,6 +127,11 @@ public class ContextHubIntentEvent {
int nanoAppAbortCode = getIntExtraOrThrow(
intent, ContextHubManager.EXTRA_NANOAPP_ABORT_CODE);
event = new ContextHubIntentEvent(info, eventType, nanoAppId, nanoAppAbortCode);
+ } else if (eventType == ContextHubManager.EVENT_CLIENT_AUTHORIZATION) {
+ int authState = getIntExtraOrThrow(
+ intent, ContextHubManager.EXTRA_CLIENT_AUTHORIZATION_STATE);
+ event = new ContextHubIntentEvent(info, eventType, nanoAppId,
+ null /* nanoAppMessage */, -1 /* nanoAppAbortCode */, authState);
} else {
event = new ContextHubIntentEvent(info, eventType, nanoAppId);
}
@@ -192,6 +204,21 @@ public class ContextHubIntentEvent {
return mNanoAppMessage;
}
+ /**
+ * @return the client authorization state
+ *
+ * @throws UnsupportedOperationException if this was not a client authorization state event
+ */
+ @ContextHubManager.AuthorizationState
+ public int getClientAuthorizationState() {
+ if (mEventType != ContextHubManager.EVENT_CLIENT_AUTHORIZATION) {
+ throw new UnsupportedOperationException(
+ "Cannot invoke getClientAuthorizationState() on non-authorization event: "
+ + mEventType);
+ }
+ return mClientAuthorizationState;
+ }
+
@NonNull
@Override
public String toString() {
@@ -207,6 +234,9 @@ public class ContextHubIntentEvent {
if (mEventType == ContextHubManager.EVENT_NANOAPP_MESSAGE) {
out += ", nanoAppMessage = " + mNanoAppMessage;
}
+ if (mEventType == ContextHubManager.EVENT_CLIENT_AUTHORIZATION) {
+ out += ", clientAuthState = " + mClientAuthorizationState;
+ }
return out + "]";
}
@@ -233,6 +263,9 @@ public class ContextHubIntentEvent {
if (mEventType == ContextHubManager.EVENT_NANOAPP_MESSAGE) {
isEqual &= other.getNanoAppMessage().equals(mNanoAppMessage);
}
+ if (mEventType == ContextHubManager.EVENT_CLIENT_AUTHORIZATION) {
+ isEqual &= other.getClientAuthorizationState() == mClientAuthorizationState;
+ }
} catch (UnsupportedOperationException e) {
isEqual = false;
}
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index d44480796d75..ebb3021bf083 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -59,6 +59,12 @@ public final class ContextHubManager {
private static final String TAG = "ContextHubManager";
/**
+ * An extra of type int describing the client's authorization state.
+ */
+ public static final String EXTRA_CLIENT_AUTHORIZATION_STATE =
+ "android.hardware.location.extra.CLIENT_AUTHORIZATION_STATE";
+
+ /**
* An extra of type {@link ContextHubInfo} describing the source of the event.
*/
public static final String EXTRA_CONTEXT_HUB_INFO =
@@ -86,6 +92,42 @@ public final class ContextHubManager {
public static final String EXTRA_MESSAGE = "android.hardware.location.extra.MESSAGE";
/**
+ * Constants describing if a {@link ContextHubClient} and a {@link NanoApp} are authorized to
+ * communicate.
+ *
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "AUTHORIZATION_" }, value = {
+ AUTHORIZATION_DENIED,
+ AUTHORIZATION_DENIED_GRACE_PERIOD,
+ AUTHORIZATION_GRANTED,
+ })
+ public @interface AuthorizationState { }
+
+ /**
+ * Indicates that the {@link ContextHubClient} can no longer communicate with a nanoapp. If the
+ * {@link ContextHubClient} attempts to send messages to the nanoapp, it will continue to
+ * receive this authorization state if the connection is still closed.
+ */
+ public static final int AUTHORIZATION_DENIED = 0;
+
+ /**
+ * Indicates the {@link ContextHubClient} will soon lose its authorization to communicate with a
+ * nanoapp. The {@link ContextHubClient} must perform any cleanup with the nanoapp as soon as
+ * possible.
+ *
+ * Note that the time between this state event and {@link AUTHORIZATION_DENIED} must be enough
+ * for the {@link ContextHubClient} to send at least one message to the nanoapp.
+ */
+ public static final int AUTHORIZATION_DENIED_GRACE_PERIOD = 1;
+
+ /**
+ * The {@link ContextHubClient} is authorized to communicate with the nanoapp.
+ */
+ public static final int AUTHORIZATION_GRANTED = 2;
+
+ /**
* Constants describing the type of events from a Context Hub.
* {@hide}
*/
@@ -98,6 +140,7 @@ public final class ContextHubManager {
EVENT_NANOAPP_ABORTED,
EVENT_NANOAPP_MESSAGE,
EVENT_HUB_RESET,
+ EVENT_CLIENT_AUTHORIZATION,
})
public @interface Event { }
@@ -138,6 +181,14 @@ public final class ContextHubManager {
*/
public static final int EVENT_HUB_RESET = 6;
+ /**
+ * An event describing a client authorization state change. See
+ * {@link ContextHubClientCallback#onClientAuthorizationChanged} for more details on when this
+ * event will be sent. Contains the EXTRA_NANOAPP_ID and EXTRA_CLIENT_AUTHORIZATION_STATE
+ * extras.
+ */
+ public static final int EVENT_CLIENT_AUTHORIZATION = 7;
+
private final Looper mMainLooper;
private final IContextHubService mService;
private Callback mCallback;
@@ -747,6 +798,14 @@ public final class ContextHubManager {
public void onNanoAppDisabled(long nanoAppId) {
executor.execute(() -> callback.onNanoAppDisabled(client, nanoAppId));
}
+
+ @Override
+ public void onClientAuthorizationChanged(
+ long nanoAppId, @ContextHubManager.AuthorizationState int authorization) {
+ executor.execute(
+ () -> callback.onClientAuthorizationChanged(
+ client, nanoAppId, authorization));
+ }
};
}
@@ -757,9 +816,10 @@ public final class ContextHubManager {
* registration succeeds, the client can send messages to nanoapps through the returned
* {@link ContextHubClient} object, and receive notifications through the provided callback.
*
+ * @param context the context of the application
* @param hubInfo the hub to attach this client to
- * @param callback the notification callback to register
* @param executor the executor to invoke the callback
+ * @param callback the notification callback to register
* @return the registered client object
*
* @throws IllegalArgumentException if hubInfo does not represent a valid hub
@@ -773,8 +833,9 @@ public final class ContextHubManager {
android.Manifest.permission.ACCESS_CONTEXT_HUB
})
@NonNull public ContextHubClient createClient(
- @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback,
- @NonNull @CallbackExecutor Executor executor) {
+ @Nullable Context context, @NonNull ContextHubInfo hubInfo,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull ContextHubClientCallback callback) {
Objects.requireNonNull(callback, "Callback cannot be null");
Objects.requireNonNull(hubInfo, "ContextHubInfo cannot be null");
Objects.requireNonNull(executor, "Executor cannot be null");
@@ -783,9 +844,14 @@ public final class ContextHubManager {
IContextHubClientCallback clientInterface = createClientCallback(
client, callback, executor);
+ String attributionTag = null;
+ if (context != null) {
+ attributionTag = context.getAttributionTag();
+ }
+
IContextHubClient clientProxy;
try {
- clientProxy = mService.createClient(hubInfo.getId(), clientInterface);
+ clientProxy = mService.createClient(hubInfo.getId(), clientInterface, attributionTag);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -794,19 +860,25 @@ public final class ContextHubManager {
return client;
}
+
+ /**
+ * Equivalent to
+ * {@link #createClient(ContextHubInfo, Executor, String, ContextHubClientCallback)}
+ * with the {@link Context} being set to null.
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.LOCATION_HARDWARE,
+ android.Manifest.permission.ACCESS_CONTEXT_HUB
+ })
+ @NonNull public ContextHubClient createClient(
+ @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback,
+ @NonNull @CallbackExecutor Executor executor) {
+ return createClient(null /* context */, hubInfo, executor, callback);
+ }
+
/**
* Equivalent to {@link #createClient(ContextHubInfo, ContextHubClientCallback, Executor)}
* with the executor using the main thread's Looper.
- *
- * @param hubInfo the hub to attach this client to
- * @param callback the notification callback to register
- * @return the registered client object
- *
- * @throws IllegalArgumentException if hubInfo does not represent a valid hub
- * @throws IllegalStateException if there were too many registered clients at the service
- * @throws NullPointerException if callback or hubInfo is null
- *
- * @see ContextHubClientCallback
*/
@RequiresPermission(anyOf = {
android.Manifest.permission.LOCATION_HARDWARE,
@@ -814,7 +886,8 @@ public final class ContextHubManager {
})
@NonNull public ContextHubClient createClient(
@NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback) {
- return createClient(hubInfo, callback, new HandlerExecutor(Handler.getMain()));
+ return createClient(null /* context */, hubInfo, new HandlerExecutor(Handler.getMain()),
+ callback);
}
/**
@@ -848,6 +921,8 @@ public final class ContextHubManager {
* on the provided PendingIntent, then the client will be automatically unregistered by the
* service.
*
+ * @param context the context of the application. If a PendingIntent client is recreated,
+ * the latest state in the context will be used and old state will be discarded
* @param hubInfo the hub to attach this client to
* @param pendingIntent the PendingIntent to register to the client
* @param nanoAppId the ID of the nanoapp that Intent events will be generated for
@@ -862,16 +937,22 @@ public final class ContextHubManager {
android.Manifest.permission.ACCESS_CONTEXT_HUB
})
@NonNull public ContextHubClient createClient(
- @NonNull ContextHubInfo hubInfo, @NonNull PendingIntent pendingIntent, long nanoAppId) {
+ @Nullable Context context, @NonNull ContextHubInfo hubInfo,
+ @NonNull PendingIntent pendingIntent, long nanoAppId) {
Objects.requireNonNull(pendingIntent);
Objects.requireNonNull(hubInfo);
ContextHubClient client = new ContextHubClient(hubInfo, true /* persistent */);
+ String attributionTag = null;
+ if (context != null) {
+ attributionTag = context.getAttributionTag();
+ }
+
IContextHubClient clientProxy;
try {
clientProxy = mService.createPendingIntentClient(
- hubInfo.getId(), pendingIntent, nanoAppId);
+ hubInfo.getId(), pendingIntent, nanoAppId, attributionTag);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -881,6 +962,19 @@ public final class ContextHubManager {
}
/**
+ * Equivalent to {@link #createClient(ContextHubInfo, PendingIntent, long, String)}
+ * with {@link Context} being set to null.
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.LOCATION_HARDWARE,
+ android.Manifest.permission.ACCESS_CONTEXT_HUB
+ })
+ @NonNull public ContextHubClient createClient(
+ @NonNull ContextHubInfo hubInfo, @NonNull PendingIntent pendingIntent, long nanoAppId) {
+ return createClient(null /* context */, hubInfo, pendingIntent, nanoAppId);
+ }
+
+ /**
* Unregister a callback for receive messages from the context hub.
*
* @see Callback
diff --git a/core/java/android/hardware/location/IContextHubClientCallback.aidl b/core/java/android/hardware/location/IContextHubClientCallback.aidl
index 1c76bcbe18ce..bcd6b087a276 100644
--- a/core/java/android/hardware/location/IContextHubClientCallback.aidl
+++ b/core/java/android/hardware/location/IContextHubClientCallback.aidl
@@ -46,4 +46,7 @@ oneway interface IContextHubClientCallback {
// Callback invoked when a nanoapp is disabled at the attached Context Hub.
void onNanoAppDisabled(long nanoAppId);
+
+ // Callback invoked when the authorization state of a client changes.
+ void onClientAuthorizationChanged(long nanoAppId, int authorization);
}
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
index 04cc5634bf2c..4961195a3017 100644
--- a/core/java/android/hardware/location/IContextHubService.aidl
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -59,11 +59,13 @@ interface IContextHubService {
int sendMessage(int contextHubHandle, int nanoAppHandle, in ContextHubMessage msg);
// Creates a client to send and receive messages
- IContextHubClient createClient(int contextHubId, in IContextHubClientCallback client);
+ IContextHubClient createClient(
+ int contextHubId, in IContextHubClientCallback client, in String attributionTag);
// Creates a PendingIntent-based client to send and receive messages
IContextHubClient createPendingIntentClient(
- int contextHubId, in PendingIntent pendingIntent, long nanoAppId);
+ int contextHubId, in PendingIntent pendingIntent, long nanoAppId,
+ in String attributionTag);
// Returns a list of ContextHub objects of available hubs
List<ContextHubInfo> getContextHubs();
diff --git a/core/java/android/hardware/location/NanoAppState.java b/core/java/android/hardware/location/NanoAppState.java
index 8de7ecd6b2b3..96b1f19a9cd5 100644
--- a/core/java/android/hardware/location/NanoAppState.java
+++ b/core/java/android/hardware/location/NanoAppState.java
@@ -15,10 +15,14 @@
*/
package android.hardware.location;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* A class describing the nanoapp state information resulting from a query to a Context Hub.
*
@@ -29,11 +33,21 @@ public final class NanoAppState implements Parcelable {
private long mNanoAppId;
private int mNanoAppVersion;
private boolean mIsEnabled;
+ private List<String> mNanoAppPermissions;
public NanoAppState(long nanoAppId, int appVersion, boolean enabled) {
mNanoAppId = nanoAppId;
mNanoAppVersion = appVersion;
mIsEnabled = enabled;
+ mNanoAppPermissions = new ArrayList<String>();
+ }
+
+ public NanoAppState(long nanoAppId, int appVersion, boolean enabled,
+ @NonNull List<String> nanoAppPermissions) {
+ mNanoAppId = nanoAppId;
+ mNanoAppVersion = appVersion;
+ mIsEnabled = enabled;
+ mNanoAppPermissions = nanoAppPermissions;
}
/**
@@ -57,10 +71,19 @@ public final class NanoAppState implements Parcelable {
return mIsEnabled;
}
+ /**
+ * @return List of Android permissions that are required to communicate with this app.
+ */
+ public @NonNull List<String> getNanoAppPermissions() {
+ return mNanoAppPermissions;
+ }
+
private NanoAppState(Parcel in) {
mNanoAppId = in.readLong();
mNanoAppVersion = in.readInt();
mIsEnabled = (in.readInt() == 1);
+ mNanoAppPermissions = new ArrayList<String>();
+ in.readStringList(mNanoAppPermissions);
}
@Override
@@ -73,6 +96,7 @@ public final class NanoAppState implements Parcelable {
out.writeLong(mNanoAppId);
out.writeInt(mNanoAppVersion);
out.writeInt(mIsEnabled ? 1 : 0);
+ out.writeStringList(mNanoAppPermissions);
}
public static final @android.annotation.NonNull Creator<NanoAppState> CREATOR =
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index c28bab7f643f..5bac481fb23e 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -1198,7 +1198,10 @@ public class UsbManager {
/**
* Returns whether the given functions are valid inputs to UsbManager.
- * Currently the empty functions or any of MTP, PTP, RNDIS, MIDI are accepted.
+ * Currently the empty functions or any of MTP, PTP, RNDIS, MIDI, NCM are accepted.
+ *
+ * Only one function may be set at a time, except for RNDIS and NCM, which can be set together
+ * because from a user perspective they are the same function (tethering).
*
* @return Whether the mask is settable.
*
@@ -1206,7 +1209,9 @@ public class UsbManager {
*/
public static boolean areSettableFunctions(long functions) {
return functions == FUNCTION_NONE
- || ((~SETTABLE_FUNCTIONS & functions) == 0 && Long.bitCount(functions) == 1);
+ || ((~SETTABLE_FUNCTIONS & functions) == 0
+ && ((Long.bitCount(functions) == 1)
+ || (functions == (FUNCTION_RNDIS | FUNCTION_NCM))));
}
/**
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 60923f5ea8c6..70bca3019818 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -707,7 +707,7 @@ public final class IpSecManager {
}
/**
- * This class represents an IpSecTunnelInterface.
+ * This class represents an IpSecTunnelInterface
*
* <p>IpSecTunnelInterface objects track tunnel interfaces that serve as
* local endpoints for IPsec tunnels.
@@ -716,7 +716,9 @@ public final class IpSecManager {
* applied to provide IPsec security to packets sent through the tunnel. While a tunnel
* cannot be used in standalone mode within Android, the higher layers may use the tunnel
* to create Network objects which are accessible to the Android system.
+ * @hide
*/
+ @SystemApi
public static final class IpSecTunnelInterface implements AutoCloseable {
private final String mOpPackageName;
private final IIpSecService mService;
@@ -727,26 +729,23 @@ public final class IpSecManager {
private String mInterfaceName;
private int mResourceId = INVALID_RESOURCE_ID;
- /**
- * Get the underlying SPI held by this object.
- *
- * @hide
- */
- @SystemApi
+ /** Get the underlying SPI held by this object. */
@NonNull
public String getInterfaceName() {
return mInterfaceName;
}
/**
- * Add an address to the IpSecTunnelInterface.
+ * Add an address to the IpSecTunnelInterface
*
* <p>Add an address which may be used as the local inner address for
* tunneled traffic.
*
* @param address the local address for traffic inside the tunnel
* @param prefixLen length of the InetAddress prefix
+ * @hide
*/
+ @SystemApi
@RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
@RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
public void addAddress(@NonNull InetAddress address, int prefixLen) throws IOException {
@@ -761,13 +760,15 @@ public final class IpSecManager {
}
/**
- * Remove an address from the IpSecTunnelInterface.
+ * Remove an address from the IpSecTunnelInterface
*
- * <p>Remove an address which was previously added to the IpSecTunnelInterface.
+ * <p>Remove an address which was previously added to the IpSecTunnelInterface
*
* @param address to be removed
* @param prefixLen length of the InetAddress prefix
+ * @hide
*/
+ @SystemApi
@RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
@RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
public void removeAddress(@NonNull InetAddress address, int prefixLen) throws IOException {
@@ -818,7 +819,7 @@ public final class IpSecManager {
}
/**
- * Delete an IpSecTunnelInterface.
+ * Delete an IpSecTunnelInterface
*
* <p>Calling close will deallocate the IpSecTunnelInterface and all of its system
* resources. Any packets bound for this interface either inbound or outbound will
@@ -840,12 +841,7 @@ public final class IpSecManager {
}
}
-
- /**
- * Check that the Interface was closed properly.
- *
- * @hide
- */
+ /** Check that the Interface was closed properly. */
@Override
protected void finalize() throws Throwable {
if (mCloseGuard != null) {
@@ -877,52 +873,17 @@ public final class IpSecManager {
* Create a new IpSecTunnelInterface as a local endpoint for tunneled IPsec traffic.
*
* <p>An application that creates tunnels is responsible for cleaning up the tunnel when the
- * underlying network disconnects, and the {@link
- * ConnectivityManager.NetworkCallback#onLost(Network)} callback is received.
- *
- * @param underlyingNetwork the {@link Network} that will carry traffic for this tunnel. Packets
- * that go through the tunnel will need a underlying network to transit to the IPsec peer.
- * This network should almost certainly be a physical network such as WiFi.
- * @return a new {@link IpSecTunnelInterface} with the specified properties
- * @throws IOException indicating that the tunnel could not be created due to a lower-layer
- * error
- * @throws ResourceUnavailableException indicating that the number of opening tunnels has
- * reached the limit.
- */
- @NonNull
- @RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
- @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
- public IpSecTunnelInterface createIpSecTunnelInterface(@NonNull Network underlyingNetwork)
- throws ResourceUnavailableException, IOException {
-
- // TODO: Remove the need for adding two unused addresses with IPsec tunnels when {@link
- // #createIpSecTunnelInterface(localAddress, remoteAddress, underlyingNetwork)} can be
- // safely removed.
- final InetAddress address = InetAddress.getLocalHost();
- return createIpSecTunnelInterface(address, address, underlyingNetwork);
- }
-
- /**
- * Create a new IpSecTunnelInterface as a local endpoint for tunneled IPsec traffic.
+ * underlying network goes away, and the onLost() callback is received.
*
- * <p>An application that creates tunnels is responsible for cleaning up the tunnel when the
- * underlying network disconnects, and the {@link
- * ConnectivityManager.NetworkCallback#onLost(Network)} callback is received.
- *
- * @param localAddress The local address of the tunnel
- * @param remoteAddress The local address of the tunnel
- * @param underlyingNetwork the {@link Network} that will carry traffic for this tunnel. Packets
- * that go through the tunnel will need a underlying network to transit to the IPsec peer.
- * This network should almost certainly be a physical network such as WiFi.
- * @return a new {@link IpSecTunnelInterface} with the specified properties
- * @throws IOException indicating that the tunnel could not be created due to a lower-layer
- * error
- * @throws ResourceUnavailableException indicating that the number of opening tunnels has
- * reached the limit.
+ * @param localAddress The local addres of the tunnel
+ * @param remoteAddress The local addres of the tunnel
+ * @param underlyingNetwork the {@link Network} that will carry traffic for this tunnel.
+ * This network should almost certainly be a network such as WiFi with an L2 address.
+ * @return a new {@link IpSecManager#IpSecTunnelInterface} with the specified properties
+ * @throws IOException indicating that the socket could not be opened or bound
+ * @throws ResourceUnavailableException indicating that too many encapsulation sockets are open
* @hide
- * @deprecated Callers should use {@link #createIpSecTunnelInterface(Network)}
*/
- @Deprecated
@SystemApi
@NonNull
@RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
@@ -946,14 +907,16 @@ public final class IpSecManager {
* <p>Applications should probably not use this API directly.
*
*
- * @param tunnel The {@link IpSecTunnelInterface} that will use the supplied
+ * @param tunnel The {@link IpSecManager#IpSecTunnelInterface} that will use the supplied
* transform.
- * @param direction the direction, {@link #DIRECTION_OUT} or {@link #DIRECTION_IN} in which
+ * @param direction the direction, {@link DIRECTION_OUT} or {@link #DIRECTION_IN} in which
* the transform will be used.
* @param transform an {@link IpSecTransform} created in tunnel mode
- * @throws IOException indicating that the transform could not be applied due to a lower-layer
- * error
+ * @throws IOException indicating that the transform could not be applied due to a lower
+ * layer failure.
+ * @hide
*/
+ @SystemApi
@RequiresFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
@RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
public void applyTunnelModeTransform(@NonNull IpSecTunnelInterface tunnel,
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
index 713b6888376e..e1ef8b5ea5c9 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -16,6 +16,7 @@
package android.net;
+import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Parcel;
@@ -30,7 +31,8 @@ import android.util.Slog;
public class NetworkState implements Parcelable {
private static final boolean VALIDATE_ROAMING_STATE = false;
- public static final NetworkState EMPTY = new NetworkState(null, null, null, null, null, null);
+ // TODO: remove and make members @NonNull.
+ public static final NetworkState EMPTY = new NetworkState();
public final NetworkInfo networkInfo;
public final LinkProperties linkProperties;
@@ -40,9 +42,18 @@ public class NetworkState implements Parcelable {
public final String subscriberId;
public final String networkId;
- public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties,
- NetworkCapabilities networkCapabilities, Network network, String subscriberId,
- String networkId) {
+ private NetworkState() {
+ networkInfo = null;
+ linkProperties = null;
+ networkCapabilities = null;
+ network = null;
+ subscriberId = null;
+ networkId = null;
+ }
+
+ public NetworkState(@NonNull NetworkInfo networkInfo, @NonNull LinkProperties linkProperties,
+ @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network,
+ String subscriberId, String networkId) {
this.networkInfo = networkInfo;
this.linkProperties = linkProperties;
this.networkCapabilities = networkCapabilities;
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 9a102a7c4b00..059e932a9da9 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -416,9 +416,21 @@ public final class PowerManager {
public static final int GO_TO_SLEEP_REASON_QUIESCENT = 10;
/**
+ * Go to sleep reason code: The last powered on display group has been removed.
* @hide
*/
- public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_QUIESCENT;
+ public static final int GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED = 11;
+
+ /**
+ * Go to sleep reason code: Every display group has been turned off.
+ * @hide
+ */
+ public static final int GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF = 12;
+
+ /**
+ * @hide
+ */
+ public static final int GO_TO_SLEEP_REASON_MAX = GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF;
/**
* @hide
@@ -435,6 +447,8 @@ public final class PowerManager {
case GO_TO_SLEEP_REASON_ACCESSIBILITY: return "accessibility";
case GO_TO_SLEEP_REASON_FORCE_SUSPEND: return "force_suspend";
case GO_TO_SLEEP_REASON_INATTENTIVE: return "inattentive";
+ case GO_TO_SLEEP_REASON_DISPLAY_GROUP_REMOVED: return "display_group_removed";
+ case GO_TO_SLEEP_REASON_DISPLAY_GROUPS_TURNED_OFF: return "display_groups_turned_off";
default: return Integer.toString(sleepReason);
}
}
@@ -521,6 +535,8 @@ public final class PowerManager {
WAKE_REASON_WAKE_KEY,
WAKE_REASON_WAKE_MOTION,
WAKE_REASON_HDMI,
+ WAKE_REASON_DISPLAY_GROUP_ADDED,
+ WAKE_REASON_DISPLAY_GROUP_TURNED_ON,
})
@Retention(RetentionPolicy.SOURCE)
public @interface WakeReason{}
@@ -608,6 +624,18 @@ public final class PowerManager {
public static final int WAKE_REASON_LID = 9;
/**
+ * Wake up reason code: Waking due to display group being added.
+ * @hide
+ */
+ public static final int WAKE_REASON_DISPLAY_GROUP_ADDED = 10;
+
+ /**
+ * Wake up reason code: Waking due to display group being powered on.
+ * @hide
+ */
+ public static final int WAKE_REASON_DISPLAY_GROUP_TURNED_ON = 11;
+
+ /**
* Convert the wake reason to a string for debugging purposes.
* @hide
*/
@@ -623,6 +651,8 @@ public final class PowerManager {
case WAKE_REASON_WAKE_MOTION: return "WAKE_REASON_WAKE_MOTION";
case WAKE_REASON_HDMI: return "WAKE_REASON_HDMI";
case WAKE_REASON_LID: return "WAKE_REASON_LID";
+ case WAKE_REASON_DISPLAY_GROUP_ADDED: return "WAKE_REASON_DISPLAY_GROUP_ADDED";
+ case WAKE_REASON_DISPLAY_GROUP_TURNED_ON: return "WAKE_REASON_DISPLAY_GROUP_TURNED_ON";
default: return Integer.toString(wakeReason);
}
}
@@ -1253,8 +1283,15 @@ public final class PowerManager {
}
}
- /**
- * Forces the device to go to sleep.
+ /**
+ * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group}
+ * to turn off.
+ *
+ * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is
+ * turned on it will be turned off. If all displays are off as a result of this action the
+ * device will be put to sleep. If the {@link com.android.server.display.DisplayGroup#DEFAULT
+ * default display group} is already off then nothing will happen.
+ *
* <p>
* Overrides all the wake locks that are held.
* This is what happens when the power key is pressed to turn off the screen.
@@ -1277,7 +1314,14 @@ public final class PowerManager {
}
/**
- * Forces the device to go to sleep.
+ * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group}
+ * to turn off.
+ *
+ * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is
+ * turned on it will be turned off. If all displays are off as a result of this action the
+ * device will be put to sleep. If the {@link com.android.server.display.DisplayGroup#DEFAULT
+ * default display group} is already off then nothing will happen.
+ *
* <p>
* Overrides all the wake locks that are held.
* This is what happens when the power key is pressed to turn off the screen.
@@ -1307,9 +1351,15 @@ public final class PowerManager {
}
/**
- * Forces the device to wake up from sleep.
+ * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group}
+ * to turn on.
+ *
+ * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is
+ * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If
+ * the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is already
+ * on then nothing will happen.
+ *
* <p>
- * If the device is currently asleep, wakes it up, otherwise does nothing.
* This is what happens when the power key is pressed to turn on the screen.
* </p><p>
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
@@ -1332,9 +1382,15 @@ public final class PowerManager {
}
/**
- * Forces the device to wake up from sleep.
+ * Forces the {@link com.android.server.display.DisplayGroup#DEFAULT default display group}
+ * to turn on.
+ *
+ * <p>If the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is
+ * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If
+ * the {@link com.android.server.display.DisplayGroup#DEFAULT default display group} is already
+ * on then nothing will happen.
+ *
* <p>
- * If the device is currently asleep, wakes it up, otherwise does nothing.
* This is what happens when the power key is pressed to turn on the screen.
* </p><p>
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
@@ -1361,9 +1417,13 @@ public final class PowerManager {
}
/**
- * Forces the device to wake up from sleep.
+ * Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on.
+ *
+ * <p>If the {@link android.view.Display#DEFAULT_DISPLAY default display} is turned off it will
+ * be turned on. Additionally, if the device is asleep it will be awoken. If the {@link
+ * android.view.Display#DEFAULT_DISPLAY default display} is already on then nothing will happen.
+ *
* <p>
- * If the device is currently asleep, wakes it up, otherwise does nothing.
* This is what happens when the power key is pressed to turn on the screen.
* </p><p>
* Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index a29b4b9adbb2..91e091c50532 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -368,6 +368,14 @@ public final class DeviceConfig {
public static final String NAMESPACE_SYSTEMUI = "systemui";
/**
+ * Namespace for system time and time zone detection related features / behavior.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String NAMESPACE_SYSTEM_TIME = "system_time";
+
+ /**
* Telephony related properties.
*
* @hide
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 79f055e882aa..f6ef8a3d8dae 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -13393,6 +13393,24 @@ public final class Settings {
"euicc_factory_reset_timeout_millis";
/**
+ * Flag to set the waiting time for euicc slot switch.
+ * Type: long
+ *
+ * @hide
+ */
+ public static final String EUICC_SWITCH_SLOT_TIMEOUT_MILLIS =
+ "euicc_switch_slot_timeout_millis";
+
+ /**
+ * Flag to set the waiting time for enabling multi SIM slot.
+ * Type: long
+ *
+ * @hide
+ */
+ public static final String ENABLE_MULTI_SLOT_TIMEOUT_MILLIS =
+ "enable_multi_slot_timeout_millis";
+
+ /**
* Flag to set the timeout for when to refresh the storage settings cached data.
* Type: long
*
@@ -14721,9 +14739,8 @@ public final class Settings {
* touch, allow the UID to propagate the touch.
* </ul>
*
- * @see android.hardware.input.InputManager#getMaximumObscuringOpacityForTouch(Context)
- * @see android.hardware.input.InputManager#setMaximumObscuringOpacityForTouch(Context,
- * float)
+ * @see android.hardware.input.InputManager#getMaximumObscuringOpacityForTouch()
+ * @see android.hardware.input.InputManager#setMaximumObscuringOpacityForTouch(float)
*
* @hide
*/
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index 4679c56de612..e3d0741b4603 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -129,14 +129,14 @@ public final class Dataset implements Parcelable {
/** @hide */
@TestApi
- @SuppressLint("ConcreteCollection")
+ @SuppressLint({"ConcreteCollection", "NullableCollection"})
public @Nullable ArrayList<AutofillId> getFieldIds() {
return mFieldIds;
}
/** @hide */
@TestApi
- @SuppressLint("ConcreteCollection")
+ @SuppressLint({"ConcreteCollection", "NullableCollection"})
public @Nullable ArrayList<AutofillValue> getFieldValues() {
return mFieldValues;
}
diff --git a/core/java/android/service/dataloader/OWNERS b/core/java/android/service/dataloader/OWNERS
new file mode 100644
index 000000000000..7f3906baed2e
--- /dev/null
+++ b/core/java/android/service/dataloader/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/os/incremental/OWNERS \ No newline at end of file
diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
index e0f3018e3d0e..44daeff76997 100644
--- a/core/java/android/service/notification/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -46,7 +46,7 @@ oneway interface INotificationListener
void onNotificationChannelGroupModification(String pkgName, in UserHandle user, in NotificationChannelGroup group, int modificationType);
// assistants only
- void onNotificationEnqueuedWithChannel(in IStatusBarNotificationHolder notificationHolder, in NotificationChannel channel);
+ void onNotificationEnqueuedWithChannel(in IStatusBarNotificationHolder notificationHolder, in NotificationChannel channel, in NotificationRankingUpdate update);
void onNotificationSnoozedUntilContext(in IStatusBarNotificationHolder notificationHolder, String snoozeCriterionId);
void onNotificationsSeen(in List<String> keys);
void onPanelRevealed(int items);
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index cf2152cc3ad4..1d49a7206023 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -126,7 +126,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS
* {@link #onNotificationEnqueued(StatusBarNotification, NotificationChannel)}.</p>
*
* @param sbn the new notification
- * @return an adjustment or null to take no action, within 100ms.
+ * @return an adjustment or null to take no action, within 200ms.
*/
abstract public @Nullable Adjustment onNotificationEnqueued(@NonNull StatusBarNotification sbn);
@@ -135,7 +135,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS
*
* @param sbn the new notification
* @param channel the channel the notification was posted to
- * @return an adjustment or null to take no action, within 100ms.
+ * @return an adjustment or null to take no action, within 200ms.
*/
public @Nullable Adjustment onNotificationEnqueued(@NonNull StatusBarNotification sbn,
@NonNull NotificationChannel channel) {
@@ -143,6 +143,20 @@ public abstract class NotificationAssistantService extends NotificationListenerS
}
/**
+ * A notification was posted by an app. Called before post.
+ *
+ * @param sbn the new notification
+ * @param channel the channel the notification was posted to
+ * @param rankingMap The current ranking map that can be used to retrieve ranking information
+ * for active notifications.
+ * @return an adjustment or null to take no action, within 200ms.
+ */
+ public @Nullable Adjustment onNotificationEnqueued(@NonNull StatusBarNotification sbn,
+ @NonNull NotificationChannel channel, @NonNull RankingMap rankingMap) {
+ return onNotificationEnqueued(sbn, channel);
+ }
+
+ /**
* Implement this method to learn when notifications are removed, how they were interacted with
* before removal, and why they were removed.
* <p>
@@ -316,7 +330,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS
private class NotificationAssistantServiceWrapper extends NotificationListenerWrapper {
@Override
public void onNotificationEnqueuedWithChannel(IStatusBarNotificationHolder sbnHolder,
- NotificationChannel channel) {
+ NotificationChannel channel, NotificationRankingUpdate update) {
StatusBarNotification sbn;
try {
sbn = sbnHolder.get();
@@ -330,9 +344,11 @@ public abstract class NotificationAssistantService extends NotificationListenerS
return;
}
+ applyUpdateLocked(update);
SomeArgs args = SomeArgs.obtain();
args.arg1 = sbn;
args.arg2 = channel;
+ args.arg3 = getCurrentRanking();
mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_ENQUEUED,
args).sendToTarget();
}
@@ -472,8 +488,9 @@ public abstract class NotificationAssistantService extends NotificationListenerS
SomeArgs args = (SomeArgs) msg.obj;
StatusBarNotification sbn = (StatusBarNotification) args.arg1;
NotificationChannel channel = (NotificationChannel) args.arg2;
+ RankingMap ranking = (RankingMap) args.arg3;
args.recycle();
- Adjustment adjustment = onNotificationEnqueued(sbn, channel);
+ Adjustment adjustment = onNotificationEnqueued(sbn, channel, ranking);
setAdjustmentIssuer(adjustment);
if (adjustment != null) {
if (!isBound()) {
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index c41e599d5cae..64cddc35d2bb 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1431,7 +1431,8 @@ public abstract class NotificationListenerService extends Service {
@Override
public void onNotificationEnqueuedWithChannel(
- IStatusBarNotificationHolder notificationHolder, NotificationChannel channel)
+ IStatusBarNotificationHolder notificationHolder, NotificationChannel channel,
+ NotificationRankingUpdate update)
throws RemoteException {
// no-op in the listener
}
diff --git a/core/java/android/service/smartspace/ISmartspaceService.aidl b/core/java/android/service/smartspace/ISmartspaceService.aidl
new file mode 100644
index 000000000000..c9c6807058af
--- /dev/null
+++ b/core/java/android/service/smartspace/ISmartspaceService.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.service.smartspace;
+
+import android.app.smartspace.SmartspaceTarget;
+import android.app.smartspace.SmartspaceTargetEvent;
+import android.app.smartspace.SmartspaceSessionId;
+import android.app.smartspace.SmartspaceConfig;
+import android.app.smartspace.ISmartspaceCallback;
+import android.content.pm.ParceledListSlice;
+
+/**
+ * Interface from the system to Smartspace service.
+ *
+ * @hide
+ */
+oneway interface ISmartspaceService {
+
+ void onCreateSmartspaceSession(in SmartspaceConfig context, in SmartspaceSessionId sessionId);
+
+ void notifySmartspaceEvent(in SmartspaceSessionId sessionId, in SmartspaceTargetEvent event);
+
+ void requestSmartspaceUpdate(in SmartspaceSessionId sessionId);
+
+ void registerSmartspaceUpdates(in SmartspaceSessionId sessionId,
+ in ISmartspaceCallback callback);
+
+ void unregisterSmartspaceUpdates(in SmartspaceSessionId sessionId,
+ in ISmartspaceCallback callback);
+
+ void onDestroySmartspaceSession(in SmartspaceSessionId sessionId);
+}
diff --git a/core/java/android/service/smartspace/SmartspaceService.java b/core/java/android/service/smartspace/SmartspaceService.java
new file mode 100644
index 000000000000..09b731091bfd
--- /dev/null
+++ b/core/java/android/service/smartspace/SmartspaceService.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2021 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.service.smartspace;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.CallSuper;
+import android.annotation.MainThread;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.app.smartspace.ISmartspaceCallback;
+import android.app.smartspace.SmartspaceConfig;
+import android.app.smartspace.SmartspaceSessionId;
+import android.app.smartspace.SmartspaceTarget;
+import android.app.smartspace.SmartspaceTargetEvent;
+import android.content.Intent;
+import android.content.pm.ParceledListSlice;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.service.smartspace.ISmartspaceService.Stub;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * A service used to share the lifecycle of smartspace UI (open, close, interaction)
+ * and also to return smartspace result on a query.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class SmartspaceService extends Service {
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ *
+ * <p>The service must also require the {@link android.permission#MANAGE_SMARTSPACE}
+ * permission.
+ *
+ * @hide
+ */
+ public static final String SERVICE_INTERFACE =
+ "android.service.smartspace.SmartspaceService";
+ private static final boolean DEBUG = false;
+ private static final String TAG = "SmartspaceService";
+ private final ArrayMap<SmartspaceSessionId, ArrayList<CallbackWrapper>> mSessionCallbacks =
+ new ArrayMap<>();
+ private Handler mHandler;
+
+ private final android.service.smartspace.ISmartspaceService mInterface = new Stub() {
+
+ @Override
+ public void onCreateSmartspaceSession(SmartspaceConfig smartspaceConfig,
+ SmartspaceSessionId sessionId) {
+ mHandler.sendMessage(
+ obtainMessage(SmartspaceService::doCreateSmartspaceSession,
+ SmartspaceService.this, smartspaceConfig, sessionId));
+ }
+
+ @Override
+ public void notifySmartspaceEvent(SmartspaceSessionId sessionId,
+ SmartspaceTargetEvent event) {
+ mHandler.sendMessage(
+ obtainMessage(SmartspaceService::notifySmartspaceEvent,
+ SmartspaceService.this, sessionId, event));
+ }
+
+ @Override
+ public void requestSmartspaceUpdate(SmartspaceSessionId sessionId) {
+ mHandler.sendMessage(
+ obtainMessage(SmartspaceService::doRequestPredictionUpdate,
+ SmartspaceService.this, sessionId));
+ }
+
+ @Override
+ public void registerSmartspaceUpdates(SmartspaceSessionId sessionId,
+ ISmartspaceCallback callback) {
+ mHandler.sendMessage(
+ obtainMessage(SmartspaceService::doRegisterSmartspaceUpdates,
+ SmartspaceService.this, sessionId, callback));
+ }
+
+ @Override
+ public void unregisterSmartspaceUpdates(SmartspaceSessionId sessionId,
+ ISmartspaceCallback callback) {
+ mHandler.sendMessage(
+ obtainMessage(SmartspaceService::doUnregisterSmartspaceUpdates,
+ SmartspaceService.this, sessionId, callback));
+ }
+
+ @Override
+ public void onDestroySmartspaceSession(SmartspaceSessionId sessionId) {
+
+ mHandler.sendMessage(
+ obtainMessage(SmartspaceService::doDestroy,
+ SmartspaceService.this, sessionId));
+ }
+ };
+
+ @CallSuper
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Log.d(TAG, "onCreate mSessionCallbacks: " + mSessionCallbacks);
+ mHandler = new Handler(Looper.getMainLooper(), null, true);
+ }
+
+ @Override
+ @NonNull
+ public final IBinder onBind(@NonNull Intent intent) {
+ Log.d(TAG, "onBind mSessionCallbacks: " + mSessionCallbacks);
+ if (SERVICE_INTERFACE.equals(intent.getAction())) {
+ return mInterface.asBinder();
+ }
+ Slog.w(TAG, "Tried to bind to wrong intent (should be "
+ + SERVICE_INTERFACE + ": " + intent);
+ return null;
+ }
+
+ private void doCreateSmartspaceSession(@NonNull SmartspaceConfig config,
+ @NonNull SmartspaceSessionId sessionId) {
+ Log.d(TAG, "doCreateSmartspaceSession mSessionCallbacks: " + mSessionCallbacks);
+ mSessionCallbacks.put(sessionId, new ArrayList<>());
+ onCreateSmartspaceSession(config, sessionId);
+ }
+
+ /**
+ * Gets called when the client calls <code> SmartspaceManager#createSmartspaceSession </code>.
+ */
+ public abstract void onCreateSmartspaceSession(@NonNull SmartspaceConfig config,
+ @NonNull SmartspaceSessionId sessionId);
+
+ /**
+ * Gets called when the client calls <code> SmartspaceSession#notifySmartspaceEvent </code>.
+ */
+ @MainThread
+ public abstract void notifySmartspaceEvent(@NonNull SmartspaceSessionId sessionId,
+ @NonNull SmartspaceTargetEvent event);
+
+ /**
+ * Gets called when the client calls <code> SmartspaceSession#requestSmartspaceUpdate </code>.
+ */
+ @MainThread
+ public abstract void onRequestSmartspaceUpdate(@NonNull SmartspaceSessionId sessionId);
+
+ private void doRegisterSmartspaceUpdates(@NonNull SmartspaceSessionId sessionId,
+ @NonNull ISmartspaceCallback callback) {
+ Log.d(TAG, "doRegisterSmartspaceUpdates mSessionCallbacks: " + mSessionCallbacks);
+ final ArrayList<CallbackWrapper> callbacks = mSessionCallbacks.get(sessionId);
+ if (callbacks == null) {
+ Slog.e(TAG, "Failed to register for updates for unknown session: " + sessionId);
+ return;
+ }
+
+ final CallbackWrapper wrapper = findCallbackWrapper(callbacks, callback);
+ if (wrapper == null) {
+ callbacks.add(new CallbackWrapper(callback,
+ callbackWrapper ->
+ mHandler.post(
+ () -> removeCallbackWrapper(callbacks, callbackWrapper))));
+ }
+ }
+
+ private void doUnregisterSmartspaceUpdates(@NonNull SmartspaceSessionId sessionId,
+ @NonNull ISmartspaceCallback callback) {
+ Log.d(TAG, "doUnregisterSmartspaceUpdates mSessionCallbacks: " + mSessionCallbacks);
+ final ArrayList<CallbackWrapper> callbacks = mSessionCallbacks.get(sessionId);
+ if (callbacks == null) {
+ Slog.e(TAG, "Failed to unregister for updates for unknown session: " + sessionId);
+ return;
+ }
+
+ final CallbackWrapper wrapper = findCallbackWrapper(callbacks, callback);
+ if (wrapper != null) {
+ removeCallbackWrapper(callbacks, wrapper);
+ }
+ }
+
+ private void doRequestPredictionUpdate(@NonNull SmartspaceSessionId sessionId) {
+ Log.d(TAG, "doRequestPredictionUpdate mSessionCallbacks: " + mSessionCallbacks);
+ // Just an optimization, if there are no callbacks, then don't bother notifying the service
+ final ArrayList<CallbackWrapper> callbacks = mSessionCallbacks.get(sessionId);
+ if (callbacks != null && !callbacks.isEmpty()) {
+ onRequestSmartspaceUpdate(sessionId);
+ }
+ }
+
+ /**
+ * Finds the callback wrapper for the given callback.
+ */
+ private CallbackWrapper findCallbackWrapper(ArrayList<CallbackWrapper> callbacks,
+ ISmartspaceCallback callback) {
+ for (int i = callbacks.size() - 1; i >= 0; i--) {
+ if (callbacks.get(i).isCallback(callback)) {
+ return callbacks.get(i);
+ }
+ }
+ return null;
+ }
+
+ private void removeCallbackWrapper(
+ ArrayList<CallbackWrapper> callbacks, CallbackWrapper wrapper) {
+ if (callbacks == null) {
+ return;
+ }
+ callbacks.remove(wrapper);
+ }
+
+ /**
+ * Gets called when the client calls <code> SmartspaceManager#destroy() </code>.
+ */
+ public abstract void onDestroySmartspaceSession(@NonNull SmartspaceSessionId sessionId);
+
+ private void doDestroy(@NonNull SmartspaceSessionId sessionId) {
+ Log.d(TAG, "doDestroy mSessionCallbacks: " + mSessionCallbacks);
+ super.onDestroy();
+ mSessionCallbacks.remove(sessionId);
+ onDestroySmartspaceSession(sessionId);
+ }
+
+ /**
+ * Used by the prediction factory to send back results the client app. The can be called
+ * in response to {@link #onRequestSmartspaceUpdate(SmartspaceSessionId)} or proactively as
+ * a result of changes in predictions.
+ */
+ public final void updateSmartspaceTargets(@NonNull SmartspaceSessionId sessionId,
+ @NonNull List<SmartspaceTarget> targets) {
+ Log.d(TAG, "updateSmartspaceTargets mSessionCallbacks: " + mSessionCallbacks);
+ List<CallbackWrapper> callbacks = mSessionCallbacks.get(sessionId);
+ if (callbacks != null) {
+ for (CallbackWrapper callback : callbacks) {
+ callback.accept(targets);
+ }
+ }
+ }
+
+ /**
+ * Destroys a smartspace session.
+ */
+ @MainThread
+ public abstract void onDestroy(@NonNull SmartspaceSessionId sessionId);
+
+ private static final class CallbackWrapper implements Consumer<List<SmartspaceTarget>>,
+ IBinder.DeathRecipient {
+
+ private final Consumer<CallbackWrapper> mOnBinderDied;
+ private ISmartspaceCallback mCallback;
+
+ CallbackWrapper(ISmartspaceCallback callback,
+ @Nullable Consumer<CallbackWrapper> onBinderDied) {
+ mCallback = callback;
+ mOnBinderDied = onBinderDied;
+ try {
+ mCallback.asBinder().linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to link to death: " + e);
+ }
+ }
+
+ public boolean isCallback(@NonNull ISmartspaceCallback callback) {
+ if (mCallback == null) {
+ Slog.e(TAG, "Callback is null, likely the binder has died.");
+ return false;
+ }
+ return mCallback.equals(callback);
+ }
+
+ @Override
+ public void accept(List<SmartspaceTarget> smartspaceTargets) {
+ try {
+ if (mCallback != null) {
+ if (DEBUG) {
+ Slog.d(TAG,
+ "CallbackWrapper.accept smartspaceTargets=" + smartspaceTargets);
+ }
+ mCallback.onResult(new ParceledListSlice(smartspaceTargets));
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error sending result:" + e);
+ }
+ }
+
+ @Override
+ public void binderDied() {
+ mCallback.asBinder().unlinkToDeath(this, 0);
+ mCallback = null;
+ if (mOnBinderDied != null) {
+ mOnBinderDied.accept(this);
+ }
+ }
+ }
+}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 68d6f3fe3743..25f80900f1cf 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -345,7 +345,8 @@ public class VoiceInteractionService extends Service {
*/
@SystemApi
@HotwordConfigResult
- public final int setHotwordDetectionConfig(@Nullable Bundle options) {
+ public final int setHotwordDetectionConfig(
+ @SuppressLint("NullableCollection") @Nullable Bundle options) {
if (mSystemService == null) {
throw new IllegalStateException("Not available until onReady() is called");
}
diff --git a/core/java/android/util/imetracing/ImeTracing.java b/core/java/android/util/imetracing/ImeTracing.java
index 723f1dd15e23..49ff237403b2 100644
--- a/core/java/android/util/imetracing/ImeTracing.java
+++ b/core/java/android/util/imetracing/ImeTracing.java
@@ -28,6 +28,8 @@ import android.util.Log;
import android.util.proto.ProtoOutputStream;
import android.view.inputmethod.InputMethodManager;
+import com.android.internal.inputmethod.Completable;
+import com.android.internal.inputmethod.ResultCallbacks;
import com.android.internal.view.IInputMethodManager;
import java.io.PrintWriter;
@@ -91,7 +93,9 @@ public abstract class ImeTracing {
* @param where
*/
public void sendToService(byte[] protoDump, int source, String where) throws RemoteException {
- mService.startProtoDump(protoDump, source, where);
+ final Completable.Void value = Completable.createVoid();
+ mService.startProtoDump(protoDump, source, where, ResultCallbacks.of(value));
+ Completable.getResult(value);
}
/**
diff --git a/core/java/android/util/imetracing/OWNERS b/core/java/android/util/imetracing/OWNERS
new file mode 100644
index 000000000000..885fd0ab9a45
--- /dev/null
+++ b/core/java/android/util/imetracing/OWNERS
@@ -0,0 +1,3 @@
+set noparent
+
+include /services/core/java/com/android/server/inputmethod/OWNERS
diff --git a/core/java/android/view/ContentInfo.java b/core/java/android/view/ContentInfo.java
index bc66ea16bb72..547bc9d49380 100644
--- a/core/java/android/view/ContentInfo.java
+++ b/core/java/android/view/ContentInfo.java
@@ -19,6 +19,7 @@ package android.view;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.content.ClipData;
import android.content.ClipDescription;
@@ -204,6 +205,7 @@ public final class ContentInfo {
* the IME.
*/
@Nullable
+ @SuppressLint("NullableCollection")
public Bundle getExtras() {
return mExtras;
}
@@ -347,7 +349,7 @@ public final class ContentInfo {
* @return this builder
*/
@NonNull
- public Builder setExtras(@Nullable Bundle extras) {
+ public Builder setExtras(@SuppressLint("NullableCollection") @Nullable Bundle extras) {
mExtras = extras;
return this;
}
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index f4b90e1f7b44..bc03222f390d 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -22,6 +22,7 @@ import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.hardware.Battery;
import android.hardware.SensorManager;
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
@@ -73,6 +74,7 @@ public final class InputDevice implements Parcelable {
private final boolean mHasMicrophone;
private final boolean mHasButtonUnderPad;
private final boolean mHasSensor;
+ private final boolean mHasBattery;
private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();
@GuardedBy("mMotionRanges")
@@ -84,6 +86,9 @@ public final class InputDevice implements Parcelable {
@GuardedBy("mMotionRanges")
private SensorManager mSensorManager;
+ @GuardedBy("mMotionRanges")
+ private Battery mBattery;
+
/**
* A mask for input source classes.
*
@@ -323,6 +328,13 @@ public final class InputDevice implements Parcelable {
public static final int SOURCE_HDMI = 0x02000000 | SOURCE_CLASS_BUTTON;
/**
+ * The input source is a sensor associated with the input device.
+ *
+ * @see #SOURCE_CLASS_NONE
+ */
+ public static final int SOURCE_SENSOR = 0x04000000 | SOURCE_CLASS_NONE;
+
+ /**
* A special input source constant that is used when filtering input devices
* to match devices that provide any type of input source.
*/
@@ -448,7 +460,7 @@ public final class InputDevice implements Parcelable {
public InputDevice(int id, int generation, int controllerNumber, String name, int vendorId,
int productId, String descriptor, boolean isExternal, int sources, int keyboardType,
KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasMicrophone,
- boolean hasButtonUnderPad, boolean hasSensor) {
+ boolean hasButtonUnderPad, boolean hasSensor, boolean hasBattery) {
mId = id;
mGeneration = generation;
mControllerNumber = controllerNumber;
@@ -464,6 +476,7 @@ public final class InputDevice implements Parcelable {
mHasMicrophone = hasMicrophone;
mHasButtonUnderPad = hasButtonUnderPad;
mHasSensor = hasSensor;
+ mHasBattery = hasBattery;
mIdentifier = new InputDeviceIdentifier(descriptor, vendorId, productId);
}
@@ -483,6 +496,7 @@ public final class InputDevice implements Parcelable {
mHasMicrophone = in.readInt() != 0;
mHasButtonUnderPad = in.readInt() != 0;
mHasSensor = in.readInt() != 0;
+ mHasBattery = in.readInt() != 0;
mIdentifier = new InputDeviceIdentifier(mDescriptor, mVendorId, mProductId);
int numRanges = in.readInt();
@@ -830,6 +844,22 @@ public final class InputDevice implements Parcelable {
}
/**
+ * Gets the battery object associated with the device, if there is one.
+ * Even if the device does not have a battery, the result is never null.
+ * Use {@link Battery#hasBattery} to determine whether a battery is
+ * present.
+ *
+ * @return The battery object associated with the device, never null.
+ */
+ @NonNull
+ public Battery getBattery() {
+ if (mBattery == null) {
+ mBattery = InputManager.getInstance().getInputDeviceBattery(mId, mHasBattery);
+ }
+ return mBattery;
+ }
+
+ /**
* Gets the sensor manager service associated with the input device.
* Even if the device does not have a sensor, the result is never null.
* Use {@link SensorManager#getSensorList} to get a full list of all supported sensors.
@@ -1051,6 +1081,7 @@ public final class InputDevice implements Parcelable {
out.writeInt(mHasMicrophone ? 1 : 0);
out.writeInt(mHasButtonUnderPad ? 1 : 0);
out.writeInt(mHasSensor ? 1 : 0);
+ out.writeInt(mHasBattery ? 1 : 0);
final int numRanges = mMotionRanges.size();
out.writeInt(numRanges);
@@ -1097,6 +1128,8 @@ public final class InputDevice implements Parcelable {
description.append(" Has Sensor: ").append(mHasSensor).append("\n");
+ description.append(" Has battery: ").append(mHasBattery).append("\n");
+
description.append(" Has mic: ").append(mHasMicrophone).append("\n");
description.append(" Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
diff --git a/core/java/android/view/InsetsFlags.java b/core/java/android/view/InsetsFlags.java
index a334907c04bc..3355252c4372 100644
--- a/core/java/android/view/InsetsFlags.java
+++ b/core/java/android/view/InsetsFlags.java
@@ -21,6 +21,8 @@ import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS;
import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
@@ -54,7 +56,15 @@ public class InsetsFlags {
@ViewDebug.FlagToString(
mask = APPEARANCE_LIGHT_NAVIGATION_BARS,
equals = APPEARANCE_LIGHT_NAVIGATION_BARS,
- name = "LIGHT_NAVIGATION_BARS")
+ name = "LIGHT_NAVIGATION_BARS"),
+ @ViewDebug.FlagToString(
+ mask = APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS,
+ equals = APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS,
+ name = "SEMI_TRANSPARENT_STATUS_BARS"),
+ @ViewDebug.FlagToString(
+ mask = APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS,
+ equals = APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS,
+ name = "SEMI_TRANSPARENT_NAVIGATION_BARS")
})
public @Appearance int appearance;
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index bf377b0bcfd7..d68e9032c19d 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -106,7 +106,9 @@ public class InsetsState implements Parcelable {
public static final int ITYPE_NAVIGATION_BAR = 1;
public static final int ITYPE_CAPTION_BAR = 2;
- public static final int ITYPE_TOP_GESTURES = 3;
+ // The always visible types are visible to all windows regardless of the z-order.
+ public static final int FIRST_ALWAYS_VISIBLE_TYPE = 3;
+ public static final int ITYPE_TOP_GESTURES = FIRST_ALWAYS_VISIBLE_TYPE;
public static final int ITYPE_BOTTOM_GESTURES = 4;
public static final int ITYPE_LEFT_GESTURES = 5;
public static final int ITYPE_RIGHT_GESTURES = 6;
@@ -117,15 +119,16 @@ public class InsetsState implements Parcelable {
public static final int ITYPE_LEFT_MANDATORY_GESTURES = 9;
public static final int ITYPE_RIGHT_MANDATORY_GESTURES = 10;
- public static final int ITYPE_LEFT_TAPPABLE_ELEMENT = 11;
- public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 12;
- public static final int ITYPE_RIGHT_TAPPABLE_ELEMENT = 13;
- public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 14;
+ public static final int ITYPE_LEFT_DISPLAY_CUTOUT = 11;
+ public static final int ITYPE_TOP_DISPLAY_CUTOUT = 12;
+ public static final int ITYPE_RIGHT_DISPLAY_CUTOUT = 13;
+ public static final int ITYPE_BOTTOM_DISPLAY_CUTOUT = 14;
+ public static final int LAST_ALWAYS_VISIBLE_TYPE = ITYPE_BOTTOM_DISPLAY_CUTOUT;
- public static final int ITYPE_LEFT_DISPLAY_CUTOUT = 15;
- public static final int ITYPE_TOP_DISPLAY_CUTOUT = 16;
- public static final int ITYPE_RIGHT_DISPLAY_CUTOUT = 17;
- public static final int ITYPE_BOTTOM_DISPLAY_CUTOUT = 18;
+ public static final int ITYPE_LEFT_TAPPABLE_ELEMENT = 15;
+ public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 16;
+ public static final int ITYPE_RIGHT_TAPPABLE_ELEMENT = 17;
+ public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 18;
/** Input method window. */
public static final int ITYPE_IME = 19;
@@ -182,6 +185,18 @@ public class InsetsState implements Parcelable {
}
/**
+ * Mirror the always visible sources from the other state. They will share the same object for
+ * the always visible types.
+ *
+ * @param other the state to mirror the mirrored sources from.
+ */
+ public void mirrorAlwaysVisibleInsetsSources(InsetsState other) {
+ for (int type = FIRST_ALWAYS_VISIBLE_TYPE; type <= LAST_ALWAYS_VISIBLE_TYPE; type++) {
+ mSources[type] = other.mSources[type];
+ }
+ }
+
+ /**
* Calculates {@link WindowInsets} based on the current source configuration.
*
* @param frame The frame to calculate the insets relative to.
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 0a1a23116941..acd25077fb5a 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -750,18 +750,22 @@ public final class SurfaceControl implements Parcelable {
private abstract static class CaptureArgs {
private final int mPixelFormat;
private final Rect mSourceCrop = new Rect();
- private final float mFrameScale;
+ private final float mFrameScaleX;
+ private final float mFrameScaleY;
private final boolean mCaptureSecureLayers;
private final boolean mAllowProtected;
private final long mUid;
+ private final boolean mGrayscale;
private CaptureArgs(Builder<? extends Builder<?>> builder) {
mPixelFormat = builder.mPixelFormat;
mSourceCrop.set(builder.mSourceCrop);
- mFrameScale = builder.mFrameScale;
+ mFrameScaleX = builder.mFrameScaleX;
+ mFrameScaleY = builder.mFrameScaleY;
mCaptureSecureLayers = builder.mCaptureSecureLayers;
mAllowProtected = builder.mAllowProtected;
mUid = builder.mUid;
+ mGrayscale = builder.mGrayscale;
}
/**
@@ -772,10 +776,12 @@ public final class SurfaceControl implements Parcelable {
abstract static class Builder<T extends Builder<T>> {
private int mPixelFormat = PixelFormat.RGBA_8888;
private final Rect mSourceCrop = new Rect();
- private float mFrameScale = 1;
+ private float mFrameScaleX = 1;
+ private float mFrameScaleY = 1;
private boolean mCaptureSecureLayers;
private boolean mAllowProtected;
private long mUid = -1;
+ private boolean mGrayscale;
/**
* The desired pixel format of the returned buffer.
@@ -798,7 +804,18 @@ public final class SurfaceControl implements Parcelable {
* The desired scale of the returned buffer. The raw screen will be scaled up/down.
*/
public T setFrameScale(float frameScale) {
- mFrameScale = frameScale;
+ mFrameScaleX = frameScale;
+ mFrameScaleY = frameScale;
+ return getThis();
+ }
+
+ /**
+ * The desired scale of the returned buffer, allowing separate values for x and y scale.
+ * The raw screen will be scaled up/down.
+ */
+ public T setFrameScale(float frameScaleX, float frameScaleY) {
+ mFrameScaleX = frameScaleX;
+ mFrameScaleY = frameScaleY;
return getThis();
}
@@ -834,6 +851,14 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * Set whether the screenshot should use grayscale or not.
+ */
+ public T setGrayscale(boolean grayscale) {
+ mGrayscale = grayscale;
+ return getThis();
+ }
+
+ /**
* Each sub class should return itself to allow the builder to chain properly
*/
abstract T getThis();
@@ -929,7 +954,7 @@ public final class SurfaceControl implements Parcelable {
/**
* The arguments class used to make layer capture requests.
*
- * @see #nativeCaptureLayers(LayerCaptureArgs)
+ * @see #nativeCaptureLayers(LayerCaptureArgs, ScreenCaptureListener)
* @hide
*/
public static class LayerCaptureArgs extends CaptureArgs {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 5c0e15639491..9a412fcd436a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -41,6 +41,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
import android.annotation.StyleRes;
+import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.annotation.UiContext;
import android.annotation.UiThread;
@@ -9030,7 +9031,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* not be null or empty if a non-null listener is passed in.
* @param listener The listener to use. This can be null to reset to the default behavior.
*/
- public void setOnReceiveContentListener(@Nullable String[] mimeTypes,
+ public void setOnReceiveContentListener(
+ @SuppressLint("NullableCollection") @Nullable String[] mimeTypes,
@Nullable OnReceiveContentListener listener) {
if (listener != null) {
Preconditions.checkArgument(mimeTypes != null && mimeTypes.length > 0,
@@ -9106,6 +9108,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return The MIME types accepted by {@link #performReceiveContent} for this view (may
* include patterns such as "image/*").
*/
+ @SuppressLint("NullableCollection")
@Nullable
public String[] getOnReceiveContentMimeTypes() {
return mOnReceiveContentMimeTypes;
@@ -21367,6 +21370,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
int height = mBottom - mTop;
int layerType = getLayerType();
+ // Hacky hack: Reset any stretch effects as those are applied during the draw pass
+ // instead of being "stateful" like other RenderNode properties
+ renderNode.clearStretch();
+
final RecordingCanvas canvas = renderNode.beginRecording(width, height);
try {
@@ -22793,6 +22800,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final Rect bounds = drawable.getBounds();
final int width = bounds.width();
final int height = bounds.height();
+
+ // Hacky hack: Reset any stretch effects as those are applied during the draw pass
+ // instead of being "stateful" like other RenderNode properties
+ renderNode.clearStretch();
+
final RecordingCanvas canvas = renderNode.beginRecording(width, height);
// Reverse left/top translation done by drawable canvas, which will
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index f5aa97a88608..8b3fb2e9e751 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -18,6 +18,7 @@ package android.view;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Bundle;
@@ -377,7 +378,8 @@ public abstract class ViewStructure {
* <p>Should only be set when the node is used for Autofill or Content Capture purposes - it
* will be ignored when used for Assist.
*/
- public void setOnReceiveContentMimeTypes(@Nullable String[] mimeTypes) {}
+ public void setOnReceiveContentMimeTypes(
+ @SuppressLint("NullableCollection") @Nullable String[] mimeTypes) {}
/**
* Sets the {@link android.text.InputType} bits of this node.
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
index 991ed5518003..227b9f402bba 100644
--- a/core/java/android/view/WindowInsetsController.java
+++ b/core/java/android/view/WindowInsetsController.java
@@ -67,13 +67,26 @@ public interface WindowInsetsController {
int APPEARANCE_LIGHT_NAVIGATION_BARS = 1 << 4;
/**
+ * Makes status bars semi-transparent with dark background and light foreground.
+ * @hide
+ */
+ int APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS = 1 << 5;
+
+ /**
+ * Makes navigation bars semi-transparent with dark background and light foreground.
+ * @hide
+ */
+ int APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS = 1 << 6;
+
+ /**
* Determines the appearance of system bars.
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = {APPEARANCE_OPAQUE_STATUS_BARS, APPEARANCE_OPAQUE_NAVIGATION_BARS,
APPEARANCE_LOW_PROFILE_BARS, APPEARANCE_LIGHT_STATUS_BARS,
- APPEARANCE_LIGHT_NAVIGATION_BARS})
+ APPEARANCE_LIGHT_NAVIGATION_BARS, APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS,
+ APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS})
@interface Appearance {
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 7faa222dd51f..fa471fa28c7f 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1555,17 +1555,26 @@ public interface WindowManager extends ViewManager {
* <li><b>Fully transparent windows</b>: This window has {@link LayoutParams#alpha} equal
* to 0.
* <li><b>One SAW window with enough transparency</b>: This window is of type {@link
- * #TYPE_APPLICATION_OVERLAY}, has {@link LayoutParams#alpha} below or equal to <b>0.8</b>
- * and it's the <b>only</b> window of type {@link #TYPE_APPLICATION_OVERLAY} from this UID
- * in the touch path.
+ * #TYPE_APPLICATION_OVERLAY}, has {@link LayoutParams#alpha} below or equal to the
+ * <a href="#MaximumOpacity">maximum obscuring opacity</a> (see below) and it's the
+ * <b>only</b> window of type {@link #TYPE_APPLICATION_OVERLAY} from this UID in the touch
+ * path.
* <li><b>Multiple SAW windows with enough transparency</b>: The multiple overlapping
* {@link #TYPE_APPLICATION_OVERLAY} windows in the
* touch path from this UID have a <b>combined obscuring opacity</b> below or equal to
- * <b>0.8</b>. See section below on how to compute this value.
+ * the <a href="#MaximumOpacity">maximum obscuring opacity</a>. See section
+ * <a href="#ObscuringOpacity">Combined obscuring opacity</a> below on how to compute this
+ * value.
* </ol>
* <p>If none of these cases hold, the touch will not be delivered and a message will be
* logged to logcat.</p>
*
+ * <a name="MaximumOpacity"></a>
+ * <h3>Maximum obscuring opacity</h3>
+ * <p>This value is <b>0.8</b>. Apps that want to gather this value from the system rather
+ * than hard-coding it might want to use {@link
+ * android.hardware.input.InputManager#getMaximumObscuringOpacityForTouch()}.</p>
+ *
* <a name="ObscuringOpacity"></a>
* <h3>Combined obscuring opacity</h3>
*
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index a76d46d1c00f..f3111bdc7471 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -858,7 +858,7 @@ public interface InputConnection {
boolean reportFullscreenMode(boolean enabled);
/**
- * Have the editor perform spell checking around the current selection.
+ * Have the editor perform spell checking for the full content.
*
* <p>The editor can ignore this method call if it does not support spell checking.
*
diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java
index 0a1aea38dd58..5980cb6c3671 100644
--- a/core/java/android/view/textservice/TextServicesManager.java
+++ b/core/java/android/view/textservice/TextServicesManager.java
@@ -187,7 +187,8 @@ public final class TextServicesManager {
* @return The spell checker session of the spell checker.
*/
@Nullable
- public SpellCheckerSession newSpellCheckerSession(@Nullable Bundle bundle,
+ public SpellCheckerSession newSpellCheckerSession(
+ @SuppressLint("NullableCollection") @Nullable Bundle bundle,
@SuppressLint("UseIcu") @Nullable Locale locale,
@NonNull SpellCheckerSessionListener listener,
@SuppressLint("ListenerLast") boolean referToSpellCheckerLanguageSettings,
@@ -277,6 +278,7 @@ public final class TextServicesManager {
* @return The list of currently enabled spell checkers.
*/
@Nullable
+ @SuppressLint("NullableCollection")
public List<SpellCheckerInfo> getEnabledSpellCheckersList() {
final SpellCheckerInfo[] enabledSpellCheckers = getEnabledSpellCheckers();
return enabledSpellCheckers != null ? Arrays.asList(enabledSpellCheckers) : null;
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 97d98fd8ec59..794b642135d0 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -220,29 +220,26 @@ public class SpellChecker implements SpellCheckerSessionListener {
}
void onPerformSpellCheck() {
- final int selectionStart = mTextView.getSelectionStart();
- final int selectionEnd = mTextView.getSelectionEnd();
- final int selectionRangeStart;
- final int selectionRangeEnd;
- if (selectionStart < selectionEnd) {
- selectionRangeStart = selectionStart;
- selectionRangeEnd = selectionEnd;
- } else {
- selectionRangeStart = selectionEnd;
- selectionRangeEnd = selectionStart;
- }
- // Expand the range so that it (hopefully) includes the current sentence.
- final int start = Math.max(0, selectionRangeStart - MIN_SENTENCE_LENGTH);
- final int end = Math.min(mTextView.length(), selectionRangeEnd + MIN_SENTENCE_LENGTH);
+ // Triggers full content spell check.
+ final int start = 0;
+ final int end = mTextView.length();
if (DBG) {
Log.d(TAG, "performSpellCheckAroundSelection: " + start + ", " + end);
}
- spellCheck(start, end);
+ spellCheck(start, end, /* forceCheckWhenEditingWord= */ true);
}
public void spellCheck(int start, int end) {
+ spellCheck(start, end, /* forceCheckWhenEditingWord= */ false);
+ }
+
+ /**
+ * Requests to do spell check for text in the range (start, end).
+ */
+ public void spellCheck(int start, int end, boolean forceCheckWhenEditingWord) {
if (DBG) {
- Log.d(TAG, "Start spell-checking: " + start + ", " + end);
+ Log.d(TAG, "Start spell-checking: " + start + ", " + end + ", "
+ + forceCheckWhenEditingWord);
}
final Locale locale = mTextView.getSpellCheckerLocale();
final boolean isSessionActive = isSessionActive();
@@ -267,7 +264,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
for (int i = 0; i < length; i++) {
final SpellParser spellParser = mSpellParsers[i];
if (spellParser.isFinished()) {
- spellParser.parse(start, end);
+ spellParser.parse(start, end, forceCheckWhenEditingWord);
return;
}
}
@@ -282,10 +279,14 @@ public class SpellChecker implements SpellCheckerSessionListener {
SpellParser spellParser = new SpellParser();
mSpellParsers[length] = spellParser;
- spellParser.parse(start, end);
+ spellParser.parse(start, end, forceCheckWhenEditingWord);
}
private void spellCheck() {
+ spellCheck(/* forceCheckWhenEditingWord= */ false);
+ }
+
+ private void spellCheck(boolean forceCheckWhenEditingWord) {
if (mSpellCheckerSession == null) return;
Editable editable = (Editable) mTextView.getText();
@@ -295,6 +296,12 @@ public class SpellChecker implements SpellCheckerSessionListener {
TextInfo[] textInfos = new TextInfo[mLength];
int textInfosCount = 0;
+ if (DBG) {
+ Log.d(TAG, "forceCheckWhenEditingWord=" + forceCheckWhenEditingWord
+ + ", mLength=" + mLength + ", cookie = " + mCookie
+ + ", sel start = " + selectionStart + ", sel end = " + selectionEnd);
+ }
+
for (int i = 0; i < mLength; i++) {
final SpellCheckSpan spellCheckSpan = mSpellCheckSpans[i];
if (mIds[i] < 0 || spellCheckSpan.isSpellCheckInProgress()) continue;
@@ -319,7 +326,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
} else {
isEditing = selectionEnd < start || selectionStart > end;
}
- if (start >= 0 && end > start && isEditing) {
+ if (start >= 0 && end > start && (forceCheckWhenEditingWord || isEditing)) {
spellCheckSpan.setSpellCheckInProgress(true);
final TextInfo textInfo = new TextInfo(editable, start, end, mCookie, mIds[i]);
textInfos[textInfosCount++] = textInfo;
@@ -546,7 +553,11 @@ public class SpellChecker implements SpellCheckerSessionListener {
private class SpellParser {
private Object mRange = new Object();
- public void parse(int start, int end) {
+ // Forces to do spell checker even user is editing the word.
+ private boolean mForceCheckWhenEditingWord;
+
+ public void parse(int start, int end, boolean forceCheckWhenEditingWord) {
+ mForceCheckWhenEditingWord = forceCheckWhenEditingWord;
final int max = mTextView.length();
final int parseEnd;
if (end > max) {
@@ -567,6 +578,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
public void stop() {
removeRangeSpan((Editable) mTextView.getText());
+ mForceCheckWhenEditingWord = false;
}
private void setRangeSpan(Editable editable, int start, int end) {
@@ -617,7 +629,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
if (DBG) {
Log.i(TAG, "No more spell check.");
}
- removeRangeSpan(editable);
+ stop();
return;
}
@@ -649,7 +661,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
if (DBG) {
Log.i(TAG, "Incorrect range span.");
}
- removeRangeSpan(editable);
+ stop();
return;
}
do {
@@ -778,7 +790,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
removeRangeSpan(editable);
}
- spellCheck();
+ spellCheck(mForceCheckWhenEditingWord);
}
private <T> void removeSpansAt(Editable editable, int offset, T[] spans) {
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index f29eb39045ae..cdb4762a4f0a 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -21,6 +21,7 @@ import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.app.ActivityManager;
import android.os.IBinder;
@@ -151,6 +152,7 @@ public class TaskOrganizer extends WindowOrganizer {
/** Gets direct child tasks (ordered from top-to-bottom) */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
@Nullable
+ @SuppressLint("NullableCollection")
public List<ActivityManager.RunningTaskInfo> getChildTasks(
@NonNull WindowContainerToken parent, @NonNull int[] activityTypes) {
try {
@@ -163,6 +165,7 @@ public class TaskOrganizer extends WindowOrganizer {
/** Gets all root tasks on a display (ordered from top-to-bottom) */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
@Nullable
+ @SuppressLint("NullableCollection")
public List<ActivityManager.RunningTaskInfo> getRootTasks(
int displayId, @NonNull int[] activityTypes) {
try {
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 99692d0736c2..7ade05cc6de1 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -5,3 +5,4 @@ per-file SimpleIconFactory.java = file:/packages/SystemUI/OWNERS
per-file NetInitiatedActivity.java = file:/location/java/android/location/OWNERS
per-file IVoice* = file:/core/java/android/service/voice/OWNERS
per-file *Hotword* = file:/core/java/android/service/voice/OWNERS
+per-file *BatteryStats* = file:/BATTERY_STATS_OWNERS
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 13358daf05a1..1f09489b3f1f 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -62,6 +62,11 @@ public final class SystemUiDeviceConfigFlags {
*/
public static final String ENABLE_NAS_FEEDBACK = "enable_nas_feedback";
+ /**
+ * Whether the Notification Assistant can label a notification not a conversation
+ */
+ public static final String ENABLE_NAS_NOT_CONVERSATION = "enable_nas_not_conversation";
+
// Flags related to screenshot intelligence
/**
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index b8c066db29af..ea2fb88a3fc7 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -18,7 +18,6 @@ package com.android.internal.os;
import android.content.Context;
import android.hardware.SensorManager;
-import android.net.ConnectivityManager;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
@@ -57,7 +56,7 @@ public class BatteryUsageStatsProvider {
mPowerCalculators.add(new CpuPowerCalculator(mPowerProfile));
mPowerCalculators.add(new MemoryPowerCalculator(mPowerProfile));
mPowerCalculators.add(new WakelockPowerCalculator(mPowerProfile));
- if (!isWifiOnlyDevice(mContext)) {
+ if (!BatteryStatsHelper.checkWifiOnly(mContext)) {
mPowerCalculators.add(new MobileRadioPowerCalculator(mPowerProfile));
}
mPowerCalculators.add(new WifiPowerCalculator(mPowerProfile));
@@ -81,14 +80,6 @@ public class BatteryUsageStatsProvider {
return mPowerCalculators;
}
- private static boolean isWifiOnlyDevice(Context context) {
- ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
- if (cm == null) {
- return false;
- }
- return !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
- }
-
/**
* Returns a snapshot of battery attribution data.
*/
diff --git a/services/core/java/com/android/server/AttributeCache.java b/core/java/com/android/internal/policy/AttributeCache.java
index 58ec836547a7..1bdad25d25bb 100644
--- a/services/core/java/com/android/server/AttributeCache.java
+++ b/core/java/com/android/internal/policy/AttributeCache.java
@@ -1,21 +1,20 @@
/*
-**
-** Copyright 2007, 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;
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -34,6 +33,7 @@ import com.android.internal.annotations.GuardedBy;
* TODO: This should be better integrated into the system so it doesn't need
* special calls from the activity manager to clear it.
*/
+/** @hide */
public final class AttributeCache {
private static final int CACHE_SIZE = 4;
private static AttributeCache sInstance = null;
@@ -54,11 +54,11 @@ public final class AttributeCache {
context = c;
}
}
-
+
public final static class Entry {
public final Context context;
public final TypedArray array;
-
+
public Entry(Context c, TypedArray ta) {
context = c;
array = ta;
@@ -70,17 +70,17 @@ public final class AttributeCache {
}
}
}
-
+
public static void init(Context context) {
if (sInstance == null) {
sInstance = new AttributeCache(context);
}
}
-
+
public static AttributeCache instance() {
return sInstance;
}
-
+
public AttributeCache(Context context) {
mContext = context;
}
@@ -115,7 +115,11 @@ public final class AttributeCache {
}
}
}
-
+
+ public Entry get(String packageName, int resId, int[] styleable) {
+ return get(packageName, resId, styleable, UserHandle.USER_CURRENT);
+ }
+
public Entry get(String packageName, int resId, int[] styleable, int userId) {
synchronized (this) {
Package pkg = mPackages.get(packageName);
@@ -143,12 +147,12 @@ public final class AttributeCache {
pkg = new Package(context);
mPackages.put(packageName, pkg);
}
-
+
if (map == null) {
map = new ArrayMap<>();
pkg.mMap.put(resId, map);
}
-
+
try {
ent = new Entry(pkg.context,
pkg.context.obtainStyledAttributes(resId, styleable));
@@ -156,7 +160,7 @@ public final class AttributeCache {
} catch (Resources.NotFoundException e) {
return null;
}
-
+
return ent;
}
}
diff --git a/services/core/java/com/android/server/wm/animation/ClipRectLRAnimation.java b/core/java/com/android/internal/policy/ClipRectLRAnimation.java
index 0db4c70e2761..4dc3cd31ac20 100644
--- a/services/core/java/com/android/server/wm/animation/ClipRectLRAnimation.java
+++ b/core/java/com/android/internal/policy/ClipRectLRAnimation.java
@@ -11,10 +11,10 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
-package com.android.server.wm.animation;
+package com.android.internal.policy;
import android.graphics.Rect;
import android.view.animation.ClipRectAnimation;
diff --git a/services/core/java/com/android/server/wm/animation/ClipRectTBAnimation.java b/core/java/com/android/internal/policy/ClipRectTBAnimation.java
index 1f5b1a3f9660..24913cf7fca2 100644
--- a/services/core/java/com/android/server/wm/animation/ClipRectTBAnimation.java
+++ b/core/java/com/android/internal/policy/ClipRectTBAnimation.java
@@ -11,16 +11,15 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
-package com.android.server.wm.animation;
+package com.android.internal.policy;
import android.graphics.Rect;
import android.view.animation.ClipRectAnimation;
import android.view.animation.Interpolator;
import android.view.animation.Transformation;
-import android.view.animation.TranslateAnimation;
/**
* Special case of ClipRectAnimation that animates only the top/bottom
diff --git a/services/core/java/com/android/server/policy/LogDecelerateInterpolator.java b/core/java/com/android/internal/policy/LogDecelerateInterpolator.java
index ed5dc6fa7a51..dee77aae01fe 100644
--- a/services/core/java/com/android/server/policy/LogDecelerateInterpolator.java
+++ b/core/java/com/android/internal/policy/LogDecelerateInterpolator.java
@@ -11,13 +11,14 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
-package com.android.server.policy;
+package com.android.internal.policy;
import android.view.animation.Interpolator;
+/** @hide */
public class LogDecelerateInterpolator implements Interpolator {
private int mBase;
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
new file mode 100644
index 000000000000..56b25b2060ea
--- /dev/null
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -0,0 +1,960 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy;
+
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
+import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
+import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
+import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN;
+import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_CLOSE;
+import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_OPEN;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.ResourceId;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
+import android.os.SystemProperties;
+import android.util.Slog;
+import android.view.WindowManager.LayoutParams;
+import android.view.WindowManager.TransitionOldType;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.AnimationUtils;
+import android.view.animation.ClipRectAnimation;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
+import android.view.animation.ScaleAnimation;
+import android.view.animation.TranslateAnimation;
+
+import com.android.internal.R;
+
+import java.util.List;
+
+/** @hide */
+public class TransitionAnimation {
+ // These are the possible states for the enter/exit activities during a thumbnail transition
+ public static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
+ public static final int THUMBNAIL_TRANSITION_EXIT_SCALE_UP = 1;
+ public static final int THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN = 2;
+ public static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;
+
+ /**
+ * Maximum duration for the clip reveal animation. This is used when there is a lot of movement
+ * involved, to make it more understandable.
+ */
+ private static final int MAX_CLIP_REVEAL_TRANSITION_DURATION = 420;
+ private static final int CLIP_REVEAL_TRANSLATION_Y_DP = 8;
+ private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336;
+
+ public static final int DEFAULT_APP_TRANSITION_DURATION = 336;
+
+ /** Fraction of animation at which the recents thumbnail becomes completely transparent */
+ private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.5f;
+
+ private final Context mContext;
+ private final String mTag;
+
+ private final LogDecelerateInterpolator mInterpolator = new LogDecelerateInterpolator(100, 0);
+ /** Interpolator to be used for animations that respond directly to a touch */
+ private final Interpolator mTouchResponseInterpolator =
+ new PathInterpolator(0.3f, 0f, 0.1f, 1f);
+ private final Interpolator mClipHorizontalInterpolator = new PathInterpolator(0, 0, 0.4f, 1f);
+ private final Interpolator mDecelerateInterpolator;
+ private final Interpolator mLinearOutSlowInInterpolator;
+ private final Interpolator mThumbnailFadeOutInterpolator;
+ private final Rect mTmpFromClipRect = new Rect();
+ private final Rect mTmpToClipRect = new Rect();
+ private final Rect mTmpRect = new Rect();
+
+ private final int mClipRevealTranslationY;
+ private final int mConfigShortAnimTime;
+ private final int mDefaultWindowAnimationStyleResId;
+
+ private final boolean mDebug;
+ private final boolean mGridLayoutRecentsEnabled;
+ private final boolean mLowRamRecentsEnabled;
+
+ public TransitionAnimation(Context context, boolean debug, String tag) {
+ mContext = context;
+ mDebug = debug;
+ mTag = tag;
+
+ mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
+ com.android.internal.R.interpolator.decelerate_cubic);
+ mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+ com.android.internal.R.interpolator.linear_out_slow_in);
+ mThumbnailFadeOutInterpolator = input -> {
+ // Linear response for first fraction, then complete after that.
+ if (input < RECENTS_THUMBNAIL_FADEOUT_FRACTION) {
+ float t = input / RECENTS_THUMBNAIL_FADEOUT_FRACTION;
+ return mLinearOutSlowInInterpolator.getInterpolation(t);
+ }
+ return 1f;
+ };
+
+ mClipRevealTranslationY = (int) (CLIP_REVEAL_TRANSLATION_Y_DP
+ * mContext.getResources().getDisplayMetrics().density);
+ mConfigShortAnimTime = context.getResources().getInteger(
+ com.android.internal.R.integer.config_shortAnimTime);
+
+ mGridLayoutRecentsEnabled = SystemProperties.getBoolean("ro.recents.grid", false);
+ mLowRamRecentsEnabled = ActivityManager.isLowRamDeviceStatic();
+
+ final TypedArray windowStyle = mContext.getTheme().obtainStyledAttributes(
+ com.android.internal.R.styleable.Window);
+ mDefaultWindowAnimationStyleResId = windowStyle.getResourceId(
+ com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
+ windowStyle.recycle();
+ }
+
+ public Animation loadKeyguardExitAnimation(int transit, int transitionFlags) {
+ if ((transitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) != 0) {
+ return null;
+ }
+ final boolean toShade =
+ (transitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0;
+ final boolean subtle =
+ (transitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) != 0;
+ return createHiddenByKeyguardExit(mContext, mInterpolator,
+ transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER, toShade, subtle);
+ }
+
+ @Nullable
+ public Animation loadKeyguardUnoccludeAnimation(LayoutParams lp) {
+ return loadAnimationRes(lp, com.android.internal.R.anim.wallpaper_open_exit);
+ }
+
+ @Nullable
+ public Animation loadVoiceActivityOpenAnimation(LayoutParams lp, boolean enter) {
+ return loadAnimationRes(lp, enter
+ ? com.android.internal.R.anim.voice_activity_open_enter
+ : com.android.internal.R.anim.voice_activity_open_exit);
+ }
+
+ @Nullable
+ public Animation loadVoiceActivityExitAnimation(LayoutParams lp, boolean enter) {
+ return loadAnimationRes(lp, enter
+ ? com.android.internal.R.anim.voice_activity_close_enter
+ : com.android.internal.R.anim.voice_activity_close_exit);
+ }
+
+ @Nullable
+ public Animation loadAppTransitionAnimation(String packageName, int resId) {
+ return loadAnimationRes(packageName, resId);
+ }
+
+ @Nullable
+ public Animation loadCrossProfileAppEnterAnimation() {
+ return loadAnimationRes("android",
+ com.android.internal.R.anim.task_open_enter_cross_profile_apps);
+ }
+
+ @Nullable
+ public Animation loadCrossProfileAppThumbnailEnterAnimation() {
+ return loadAnimationRes(
+ "android", com.android.internal.R.anim.cross_profile_apps_thumbnail_enter);
+ }
+
+ @Nullable
+ private Animation loadAnimationRes(LayoutParams lp, int resId) {
+ Context context = mContext;
+ if (ResourceId.isValid(resId)) {
+ AttributeCache.Entry ent = getCachedAnimations(lp);
+ if (ent != null) {
+ context = ent.context;
+ }
+ return loadAnimationSafely(context, resId, mTag);
+ }
+ return null;
+ }
+
+ @Nullable
+ private Animation loadAnimationRes(String packageName, int resId) {
+ if (ResourceId.isValid(resId)) {
+ AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
+ if (ent != null) {
+ return loadAnimationSafely(ent.context, resId, mTag);
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ public Animation loadAnimationAttr(LayoutParams lp, int animAttr, int transit) {
+ int resId = Resources.ID_NULL;
+ Context context = mContext;
+ if (animAttr >= 0) {
+ AttributeCache.Entry ent = getCachedAnimations(lp);
+ if (ent != null) {
+ context = ent.context;
+ resId = ent.array.getResourceId(animAttr, 0);
+ }
+ }
+ resId = updateToTranslucentAnimIfNeeded(resId, transit);
+ if (ResourceId.isValid(resId)) {
+ return loadAnimationSafely(context, resId, mTag);
+ }
+ return null;
+ }
+
+ @Nullable
+ private AttributeCache.Entry getCachedAnimations(LayoutParams lp) {
+ if (mDebug) {
+ Slog.v(mTag, "Loading animations: layout params pkg="
+ + (lp != null ? lp.packageName : null)
+ + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
+ }
+ if (lp != null && lp.windowAnimations != 0) {
+ // If this is a system resource, don't try to load it from the
+ // application resources. It is nice to avoid loading application
+ // resources if we can.
+ String packageName = lp.packageName != null ? lp.packageName : "android";
+ int resId = getAnimationStyleResId(lp);
+ if ((resId & 0xFF000000) == 0x01000000) {
+ packageName = "android";
+ }
+ if (mDebug) {
+ Slog.v(mTag, "Loading animations: picked package=" + packageName);
+ }
+ return AttributeCache.instance().get(packageName, resId,
+ com.android.internal.R.styleable.WindowAnimation);
+ }
+ return null;
+ }
+
+ @Nullable
+ private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
+ if (mDebug) {
+ Slog.v(mTag, "Loading animations: package="
+ + packageName + " resId=0x" + Integer.toHexString(resId));
+ }
+ if (packageName != null) {
+ if ((resId & 0xFF000000) == 0x01000000) {
+ packageName = "android";
+ }
+ if (mDebug) {
+ Slog.v(mTag, "Loading animations: picked package="
+ + packageName);
+ }
+ return AttributeCache.instance().get(packageName, resId,
+ com.android.internal.R.styleable.WindowAnimation);
+ }
+ return null;
+ }
+
+ /** Returns window animation style ID from {@link LayoutParams} or from system in some cases */
+ public int getAnimationStyleResId(@NonNull LayoutParams lp) {
+ int resId = lp.windowAnimations;
+ if (lp.type == LayoutParams.TYPE_APPLICATION_STARTING) {
+ // Note that we don't want application to customize starting window animation.
+ // Since this window is specific for displaying while app starting,
+ // application should not change its animation directly.
+ // In this case, it will use system resource to get default animation.
+ resId = mDefaultWindowAnimationStyleResId;
+ }
+ return resId;
+ }
+
+ public Animation createRelaunchAnimation(Rect containingFrame, Rect contentInsets,
+ Rect startRect) {
+ setupDefaultNextAppTransitionStartRect(startRect, mTmpFromClipRect);
+ final int left = mTmpFromClipRect.left;
+ final int top = mTmpFromClipRect.top;
+ mTmpFromClipRect.offset(-left, -top);
+ // TODO: Isn't that strange that we ignore exact position of the containingFrame?
+ mTmpToClipRect.set(0, 0, containingFrame.width(), containingFrame.height());
+ AnimationSet set = new AnimationSet(true);
+ float fromWidth = mTmpFromClipRect.width();
+ float toWidth = mTmpToClipRect.width();
+ float fromHeight = mTmpFromClipRect.height();
+ // While the window might span the whole display, the actual content will be cropped to the
+ // system decoration frame, for example when the window is docked. We need to take into
+ // account the visible height when constructing the animation.
+ float toHeight = mTmpToClipRect.height() - contentInsets.top - contentInsets.bottom;
+ int translateAdjustment = 0;
+ if (fromWidth <= toWidth && fromHeight <= toHeight) {
+ // The final window is larger in both dimensions than current window (e.g. we are
+ // maximizing), so we can simply unclip the new window and there will be no disappearing
+ // frame.
+ set.addAnimation(new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect));
+ } else {
+ // The disappearing window has one larger dimension. We need to apply scaling, so the
+ // first frame of the entry animation matches the old window.
+ set.addAnimation(new ScaleAnimation(fromWidth / toWidth, 1, fromHeight / toHeight, 1));
+ // We might not be going exactly full screen, but instead be aligned under the status
+ // bar using cropping. We still need to account for the cropped part, which will also
+ // be scaled.
+ translateAdjustment = (int) (contentInsets.top * fromHeight / toHeight);
+ }
+
+ // We animate the translation from the old position of the removed window, to the new
+ // position of the added window. The latter might not be full screen, for example docked for
+ // docked windows.
+ TranslateAnimation translate = new TranslateAnimation(left - containingFrame.left,
+ 0, top - containingFrame.top - translateAdjustment, 0);
+ set.addAnimation(translate);
+ set.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+ set.setZAdjustment(Animation.ZORDER_TOP);
+ return set;
+ }
+
+ private void setupDefaultNextAppTransitionStartRect(Rect startRect, Rect rect) {
+ if (startRect == null) {
+ Slog.e(mTag, "Starting rect for app requested, but none available", new Throwable());
+ rect.setEmpty();
+ } else {
+ rect.set(startRect);
+ }
+ }
+
+ public Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame,
+ Rect displayFrame, Rect startRect) {
+ final Animation anim;
+ if (enter) {
+ final int appWidth = appFrame.width();
+ final int appHeight = appFrame.height();
+
+ // mTmpRect will contain an area around the launcher icon that was pressed. We will
+ // clip reveal from that area in the final area of the app.
+ setupDefaultNextAppTransitionStartRect(startRect, mTmpRect);
+
+ float t = 0f;
+ if (appHeight > 0) {
+ t = (float) mTmpRect.top / displayFrame.height();
+ }
+ int translationY = mClipRevealTranslationY + (int) (displayFrame.height() / 7f * t);
+ int translationX = 0;
+ int translationYCorrection = translationY;
+ int centerX = mTmpRect.centerX();
+ int centerY = mTmpRect.centerY();
+ int halfWidth = mTmpRect.width() / 2;
+ int halfHeight = mTmpRect.height() / 2;
+ int clipStartX = centerX - halfWidth - appFrame.left;
+ int clipStartY = centerY - halfHeight - appFrame.top;
+ boolean cutOff = false;
+
+ // If the starting rectangle is fully or partially outside of the target rectangle, we
+ // need to start the clipping at the edge and then achieve the rest with translation
+ // and extending the clip rect from that edge.
+ if (appFrame.top > centerY - halfHeight) {
+ translationY = (centerY - halfHeight) - appFrame.top;
+ translationYCorrection = 0;
+ clipStartY = 0;
+ cutOff = true;
+ }
+ if (appFrame.left > centerX - halfWidth) {
+ translationX = (centerX - halfWidth) - appFrame.left;
+ clipStartX = 0;
+ cutOff = true;
+ }
+ if (appFrame.right < centerX + halfWidth) {
+ translationX = (centerX + halfWidth) - appFrame.right;
+ clipStartX = appWidth - mTmpRect.width();
+ cutOff = true;
+ }
+ final long duration = calculateClipRevealTransitionDuration(cutOff, translationX,
+ translationY, displayFrame);
+
+ // Clip third of the from size of launch icon, expand to full width/height
+ Animation clipAnimLR = new ClipRectLRAnimation(
+ clipStartX, clipStartX + mTmpRect.width(), 0, appWidth);
+ clipAnimLR.setInterpolator(mClipHorizontalInterpolator);
+ clipAnimLR.setDuration((long) (duration / 2.5f));
+
+ TranslateAnimation translate = new TranslateAnimation(translationX, 0, translationY, 0);
+ translate.setInterpolator(cutOff ? mTouchResponseInterpolator
+ : mLinearOutSlowInInterpolator);
+ translate.setDuration(duration);
+
+ Animation clipAnimTB = new ClipRectTBAnimation(
+ clipStartY, clipStartY + mTmpRect.height(),
+ 0, appHeight,
+ translationYCorrection, 0,
+ mLinearOutSlowInInterpolator);
+ clipAnimTB.setInterpolator(mTouchResponseInterpolator);
+ clipAnimTB.setDuration(duration);
+
+ // Quick fade-in from icon to app window
+ final long alphaDuration = duration / 4;
+ AlphaAnimation alpha = new AlphaAnimation(0.5f, 1);
+ alpha.setDuration(alphaDuration);
+ alpha.setInterpolator(mLinearOutSlowInInterpolator);
+
+ AnimationSet set = new AnimationSet(false);
+ set.addAnimation(clipAnimLR);
+ set.addAnimation(clipAnimTB);
+ set.addAnimation(translate);
+ set.addAnimation(alpha);
+ set.setZAdjustment(Animation.ZORDER_TOP);
+ set.initialize(appWidth, appHeight, appWidth, appHeight);
+ anim = set;
+ } else {
+ final long duration;
+ switch (transit) {
+ case TRANSIT_OLD_ACTIVITY_OPEN:
+ case TRANSIT_OLD_ACTIVITY_CLOSE:
+ duration = mConfigShortAnimTime;
+ break;
+ default:
+ duration = DEFAULT_APP_TRANSITION_DURATION;
+ break;
+ }
+ if (transit == TRANSIT_OLD_WALLPAPER_INTRA_OPEN
+ || transit == TRANSIT_OLD_WALLPAPER_INTRA_CLOSE) {
+ // If we are on top of the wallpaper, we need an animation that
+ // correctly handles the wallpaper staying static behind all of
+ // the animated elements. To do this, will just have the existing
+ // element fade out.
+ anim = new AlphaAnimation(1, 0);
+ anim.setDetachWallpaper(true);
+ } else {
+ // For normal animations, the exiting element just holds in place.
+ anim = new AlphaAnimation(1, 1);
+ }
+ anim.setInterpolator(mDecelerateInterpolator);
+ anim.setDuration(duration);
+ anim.setFillAfter(true);
+ }
+ return anim;
+ }
+
+ public Animation createScaleUpAnimationLocked(int transit, boolean enter,
+ Rect containingFrame, Rect startRect) {
+ Animation a;
+ setupDefaultNextAppTransitionStartRect(startRect, mTmpRect);
+ final int appWidth = containingFrame.width();
+ final int appHeight = containingFrame.height();
+ if (enter) {
+ // Entering app zooms out from the center of the initial rect.
+ float scaleW = mTmpRect.width() / (float) appWidth;
+ float scaleH = mTmpRect.height() / (float) appHeight;
+ Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
+ computePivot(mTmpRect.left, scaleW),
+ computePivot(mTmpRect.top, scaleH));
+ scale.setInterpolator(mDecelerateInterpolator);
+
+ Animation alpha = new AlphaAnimation(0, 1);
+ alpha.setInterpolator(mThumbnailFadeOutInterpolator);
+
+ AnimationSet set = new AnimationSet(false);
+ set.addAnimation(scale);
+ set.addAnimation(alpha);
+ set.setDetachWallpaper(true);
+ a = set;
+ } else if (transit == TRANSIT_OLD_WALLPAPER_INTRA_OPEN
+ || transit == TRANSIT_OLD_WALLPAPER_INTRA_CLOSE) {
+ // If we are on top of the wallpaper, we need an animation that
+ // correctly handles the wallpaper staying static behind all of
+ // the animated elements. To do this, will just have the existing
+ // element fade out.
+ a = new AlphaAnimation(1, 0);
+ a.setDetachWallpaper(true);
+ } else {
+ // For normal animations, the exiting element just holds in place.
+ a = new AlphaAnimation(1, 1);
+ }
+
+ // Pick the desired duration. If this is an inter-activity transition,
+ // it is the standard duration for that. Otherwise we use the longer
+ // task transition duration.
+ final long duration;
+ switch (transit) {
+ case TRANSIT_OLD_ACTIVITY_OPEN:
+ case TRANSIT_OLD_ACTIVITY_CLOSE:
+ duration = mConfigShortAnimTime;
+ break;
+ default:
+ duration = DEFAULT_APP_TRANSITION_DURATION;
+ break;
+ }
+ a.setDuration(duration);
+ a.setFillAfter(true);
+ a.setInterpolator(mDecelerateInterpolator);
+ a.initialize(appWidth, appHeight, appWidth, appHeight);
+ return a;
+ }
+
+ /**
+ * This animation is created when we are doing a thumbnail transition, for the activity that is
+ * leaving, and the activity that is entering.
+ */
+ public Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState,
+ Rect containingFrame, int transit, HardwareBuffer thumbnailHeader,
+ Rect startRect) {
+ final int appWidth = containingFrame.width();
+ final int appHeight = containingFrame.height();
+ Animation a;
+ setupDefaultNextAppTransitionStartRect(startRect, mTmpRect);
+ final int thumbWidthI = thumbnailHeader != null ? thumbnailHeader.getWidth() : appWidth;
+ final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
+ final int thumbHeightI = thumbnailHeader != null ? thumbnailHeader.getHeight() : appHeight;
+ final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
+
+ switch (thumbTransitState) {
+ case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
+ // Entering app scales up with the thumbnail
+ float scaleW = thumbWidth / appWidth;
+ float scaleH = thumbHeight / appHeight;
+ a = new ScaleAnimation(scaleW, 1, scaleH, 1,
+ computePivot(mTmpRect.left, scaleW),
+ computePivot(mTmpRect.top, scaleH));
+ break;
+ }
+ case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
+ // Exiting app while the thumbnail is scaling up should fade or stay in place
+ if (transit == TRANSIT_OLD_WALLPAPER_INTRA_OPEN) {
+ // Fade out while bringing up selected activity. This keeps the
+ // current activity from showing through a launching wallpaper
+ // activity.
+ a = new AlphaAnimation(1, 0);
+ } else {
+ // noop animation
+ a = new AlphaAnimation(1, 1);
+ }
+ break;
+ }
+ case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
+ // Entering the other app, it should just be visible while we scale the thumbnail
+ // down above it
+ a = new AlphaAnimation(1, 1);
+ break;
+ }
+ case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
+ // Exiting the current app, the app should scale down with the thumbnail
+ float scaleW = thumbWidth / appWidth;
+ float scaleH = thumbHeight / appHeight;
+ Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
+ computePivot(mTmpRect.left, scaleW),
+ computePivot(mTmpRect.top, scaleH));
+
+ Animation alpha = new AlphaAnimation(1, 0);
+
+ AnimationSet set = new AnimationSet(true);
+ set.addAnimation(scale);
+ set.addAnimation(alpha);
+ set.setZAdjustment(Animation.ZORDER_TOP);
+ a = set;
+ break;
+ }
+ default:
+ throw new RuntimeException("Invalid thumbnail transition state");
+ }
+
+ return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
+ }
+
+ /**
+ * This alternate animation is created when we are doing a thumbnail transition, for the
+ * activity that is leaving, and the activity that is entering.
+ */
+ public Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState,
+ int orientation, int transit, Rect containingFrame, Rect contentInsets,
+ @Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean freeform,
+ Rect startRect, Rect defaultStartRect) {
+ Animation a;
+ final int appWidth = containingFrame.width();
+ final int appHeight = containingFrame.height();
+ setupDefaultNextAppTransitionStartRect(defaultStartRect, mTmpRect);
+ final int thumbWidthI = mTmpRect.width();
+ final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
+ final int thumbHeightI = mTmpRect.height();
+ final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
+ final int thumbStartX = mTmpRect.left - containingFrame.left - contentInsets.left;
+ final int thumbStartY = mTmpRect.top - containingFrame.top;
+
+ switch (thumbTransitState) {
+ case THUMBNAIL_TRANSITION_ENTER_SCALE_UP:
+ case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
+ final boolean scaleUp = thumbTransitState == THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
+ if (freeform && scaleUp) {
+ a = createAspectScaledThumbnailEnterFreeformAnimationLocked(
+ containingFrame, surfaceInsets, startRect, defaultStartRect);
+ } else if (freeform) {
+ a = createAspectScaledThumbnailExitFreeformAnimationLocked(
+ containingFrame, surfaceInsets, startRect, defaultStartRect);
+ } else {
+ AnimationSet set = new AnimationSet(true);
+
+ // In portrait, we scale to fit the width
+ mTmpFromClipRect.set(containingFrame);
+ mTmpToClipRect.set(containingFrame);
+
+ // Containing frame is in screen space, but we need the clip rect in the
+ // app space.
+ mTmpFromClipRect.offsetTo(0, 0);
+ mTmpToClipRect.offsetTo(0, 0);
+
+ // Exclude insets region from the source clip.
+ mTmpFromClipRect.inset(contentInsets);
+
+ if (shouldScaleDownThumbnailTransition(orientation)) {
+ // We scale the width and clip to the top/left square
+ float scale =
+ thumbWidth / (appWidth - contentInsets.left - contentInsets.right);
+ if (!mGridLayoutRecentsEnabled) {
+ int unscaledThumbHeight = (int) (thumbHeight / scale);
+ mTmpFromClipRect.bottom = mTmpFromClipRect.top + unscaledThumbHeight;
+ }
+
+ Animation scaleAnim = new ScaleAnimation(
+ scaleUp ? scale : 1, scaleUp ? 1 : scale,
+ scaleUp ? scale : 1, scaleUp ? 1 : scale,
+ containingFrame.width() / 2f,
+ containingFrame.height() / 2f + contentInsets.top);
+ final float targetX = (mTmpRect.left - containingFrame.left);
+ final float x = containingFrame.width() / 2f
+ - containingFrame.width() / 2f * scale;
+ final float targetY = (mTmpRect.top - containingFrame.top);
+ float y = containingFrame.height() / 2f
+ - containingFrame.height() / 2f * scale;
+
+ // During transition may require clipping offset from any top stable insets
+ // such as the statusbar height when statusbar is hidden
+ if (mLowRamRecentsEnabled && contentInsets.top == 0 && scaleUp) {
+ mTmpFromClipRect.top += stableInsets.top;
+ y += stableInsets.top;
+ }
+ final float startX = targetX - x;
+ final float startY = targetY - y;
+ Animation clipAnim = scaleUp
+ ? new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect)
+ : new ClipRectAnimation(mTmpToClipRect, mTmpFromClipRect);
+ Animation translateAnim = scaleUp
+ ? createCurvedMotion(startX, 0, startY - contentInsets.top, 0)
+ : createCurvedMotion(0, startX, 0, startY - contentInsets.top);
+
+ set.addAnimation(clipAnim);
+ set.addAnimation(scaleAnim);
+ set.addAnimation(translateAnim);
+
+ } else {
+ // In landscape, we don't scale at all and only crop
+ mTmpFromClipRect.bottom = mTmpFromClipRect.top + thumbHeightI;
+ mTmpFromClipRect.right = mTmpFromClipRect.left + thumbWidthI;
+
+ Animation clipAnim = scaleUp
+ ? new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect)
+ : new ClipRectAnimation(mTmpToClipRect, mTmpFromClipRect);
+ Animation translateAnim = scaleUp
+ ? createCurvedMotion(thumbStartX, 0,
+ thumbStartY - contentInsets.top, 0)
+ : createCurvedMotion(0, thumbStartX, 0,
+ thumbStartY - contentInsets.top);
+
+ set.addAnimation(clipAnim);
+ set.addAnimation(translateAnim);
+ }
+ a = set;
+ a.setZAdjustment(Animation.ZORDER_TOP);
+ }
+ break;
+ }
+ case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
+ // Previous app window during the scale up
+ if (transit == TRANSIT_OLD_WALLPAPER_INTRA_OPEN) {
+ // Fade out the source activity if we are animating to a wallpaper
+ // activity.
+ a = new AlphaAnimation(1, 0);
+ } else {
+ a = new AlphaAnimation(1, 1);
+ }
+ break;
+ }
+ case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
+ // Target app window during the scale down
+ if (transit == TRANSIT_OLD_WALLPAPER_INTRA_OPEN) {
+ // Fade in the destination activity if we are animating from a wallpaper
+ // activity.
+ a = new AlphaAnimation(0, 1);
+ } else {
+ a = new AlphaAnimation(1, 1);
+ }
+ break;
+ }
+ default:
+ throw new RuntimeException("Invalid thumbnail transition state");
+ }
+
+ return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight,
+ THUMBNAIL_APP_TRANSITION_DURATION, mTouchResponseInterpolator);
+ }
+
+ /**
+ * Prepares the specified animation with a standard duration, interpolator, etc.
+ */
+ private Animation prepareThumbnailAnimation(Animation a, int appWidth, int appHeight,
+ int transit) {
+ // Pick the desired duration. If this is an inter-activity transition,
+ // it is the standard duration for that. Otherwise we use the longer
+ // task transition duration.
+ final int duration;
+ switch (transit) {
+ case TRANSIT_OLD_ACTIVITY_OPEN:
+ case TRANSIT_OLD_ACTIVITY_CLOSE:
+ duration = mConfigShortAnimTime;
+ break;
+ default:
+ duration = DEFAULT_APP_TRANSITION_DURATION;
+ break;
+ }
+ return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
+ mDecelerateInterpolator);
+ }
+
+
+ private Animation createAspectScaledThumbnailEnterFreeformAnimationLocked(Rect frame,
+ @Nullable Rect surfaceInsets, @Nullable Rect startRect,
+ @Nullable Rect defaultStartRect) {
+ getNextAppTransitionStartRect(startRect, defaultStartRect, mTmpRect);
+ return createAspectScaledThumbnailFreeformAnimationLocked(mTmpRect, frame, surfaceInsets,
+ true);
+ }
+
+ private Animation createAspectScaledThumbnailExitFreeformAnimationLocked(Rect frame,
+ @Nullable Rect surfaceInsets, @Nullable Rect startRect,
+ @Nullable Rect defaultStartRect) {
+ getNextAppTransitionStartRect(startRect, defaultStartRect, mTmpRect);
+ return createAspectScaledThumbnailFreeformAnimationLocked(frame, mTmpRect, surfaceInsets,
+ false);
+ }
+
+ private void getNextAppTransitionStartRect(Rect startRect, Rect defaultStartRect, Rect rect) {
+ if (startRect == null && defaultStartRect == null) {
+ Slog.e(mTag, "Starting rect for container not available", new Throwable());
+ rect.setEmpty();
+ } else {
+ rect.set(startRect != null ? startRect : defaultStartRect);
+ }
+ }
+
+ private AnimationSet createAspectScaledThumbnailFreeformAnimationLocked(Rect sourceFrame,
+ Rect destFrame, @Nullable Rect surfaceInsets, boolean enter) {
+ final float sourceWidth = sourceFrame.width();
+ final float sourceHeight = sourceFrame.height();
+ final float destWidth = destFrame.width();
+ final float destHeight = destFrame.height();
+ final float scaleH = enter ? sourceWidth / destWidth : destWidth / sourceWidth;
+ final float scaleV = enter ? sourceHeight / destHeight : destHeight / sourceHeight;
+ AnimationSet set = new AnimationSet(true);
+ final int surfaceInsetsH = surfaceInsets == null
+ ? 0 : surfaceInsets.left + surfaceInsets.right;
+ final int surfaceInsetsV = surfaceInsets == null
+ ? 0 : surfaceInsets.top + surfaceInsets.bottom;
+ // We want the scaling to happen from the center of the surface. In order to achieve that,
+ // we need to account for surface insets that will be used to enlarge the surface.
+ final float scaleHCenter = ((enter ? destWidth : sourceWidth) + surfaceInsetsH) / 2;
+ final float scaleVCenter = ((enter ? destHeight : sourceHeight) + surfaceInsetsV) / 2;
+ final ScaleAnimation scale = enter
+ ? new ScaleAnimation(scaleH, 1, scaleV, 1, scaleHCenter, scaleVCenter)
+ : new ScaleAnimation(1, scaleH, 1, scaleV, scaleHCenter, scaleVCenter);
+ final int sourceHCenter = sourceFrame.left + sourceFrame.width() / 2;
+ final int sourceVCenter = sourceFrame.top + sourceFrame.height() / 2;
+ final int destHCenter = destFrame.left + destFrame.width() / 2;
+ final int destVCenter = destFrame.top + destFrame.height() / 2;
+ final int fromX = enter ? sourceHCenter - destHCenter : destHCenter - sourceHCenter;
+ final int fromY = enter ? sourceVCenter - destVCenter : destVCenter - sourceVCenter;
+ final TranslateAnimation translation = enter ? new TranslateAnimation(fromX, 0, fromY, 0)
+ : new TranslateAnimation(0, fromX, 0, fromY);
+ set.addAnimation(scale);
+ set.addAnimation(translation);
+ return set;
+ }
+
+ /**
+ * @return whether the transition should show the thumbnail being scaled down.
+ */
+ private boolean shouldScaleDownThumbnailTransition(int orientation) {
+ return mGridLayoutRecentsEnabled
+ || orientation == Configuration.ORIENTATION_PORTRAIT;
+ }
+
+ private static int updateToTranslucentAnimIfNeeded(int anim, @TransitionOldType int transit) {
+ if (transit == TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN
+ && anim == R.anim.activity_open_enter) {
+ return R.anim.activity_translucent_open_enter;
+ }
+ if (transit == TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE
+ && anim == R.anim.activity_close_exit) {
+ return R.anim.activity_translucent_close_exit;
+ }
+ return anim;
+ }
+
+ /**
+ * Calculates the duration for the clip reveal animation. If the clip is "cut off", meaning that
+ * the start rect is outside of the target rect, and there is a lot of movement going on.
+ *
+ * @param cutOff whether the start rect was not fully contained by the end rect
+ * @param translationX the total translation the surface moves in x direction
+ * @param translationY the total translation the surfaces moves in y direction
+ * @param displayFrame our display frame
+ *
+ * @return the duration of the clip reveal animation, in milliseconds
+ */
+ private static long calculateClipRevealTransitionDuration(boolean cutOff, float translationX,
+ float translationY, Rect displayFrame) {
+ if (!cutOff) {
+ return DEFAULT_APP_TRANSITION_DURATION;
+ }
+ final float fraction = Math.max(Math.abs(translationX) / displayFrame.width(),
+ Math.abs(translationY) / displayFrame.height());
+ return (long) (DEFAULT_APP_TRANSITION_DURATION + fraction
+ * (MAX_CLIP_REVEAL_TRANSITION_DURATION - DEFAULT_APP_TRANSITION_DURATION));
+ }
+
+ /**
+ * Prepares the specified animation with a standard duration, interpolator, etc.
+ */
+ private static Animation prepareThumbnailAnimationWithDuration(Animation a, int appWidth,
+ int appHeight, long duration, Interpolator interpolator) {
+ if (duration > 0) {
+ a.setDuration(duration);
+ }
+ a.setFillAfter(true);
+ if (interpolator != null) {
+ a.setInterpolator(interpolator);
+ }
+ a.initialize(appWidth, appHeight, appWidth, appHeight);
+ return a;
+ }
+
+ private static Animation createCurvedMotion(float fromX, float toX, float fromY, float toY) {
+ return new TranslateAnimation(fromX, toX, fromY, toY);
+ }
+
+ /**
+ * Compute the pivot point for an animation that is scaling from a small
+ * rect on screen to a larger rect. The pivot point varies depending on
+ * the distance between the inner and outer edges on both sides. This
+ * function computes the pivot point for one dimension.
+ * @param startPos Offset from left/top edge of outer rectangle to
+ * left/top edge of inner rectangle.
+ * @param finalScale The scaling factor between the size of the outer
+ * and inner rectangles.
+ */
+ public static float computePivot(int startPos, float finalScale) {
+
+ /*
+ Theorem of intercepting lines:
+
+ + + +-----------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ x | y | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | + | +--------------------+ |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | | | |
+ | | +--------------------+ |
+ | | |
+ | | |
+ | | |
+ | | |
+ | | |
+ | | |
+ | | |
+ | +-----------------------------------------------+
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ + ++
+ p ++
+
+ scale = (x - y) / x
+ <=> x = -y / (scale - 1)
+ */
+ final float denom = finalScale - 1;
+ if (Math.abs(denom) < .0001f) {
+ return startPos;
+ }
+ return -startPos / denom;
+ }
+
+ @Nullable
+ public static Animation loadAnimationSafely(Context context, int resId, String tag) {
+ try {
+ return AnimationUtils.loadAnimation(context, resId);
+ } catch (Resources.NotFoundException e) {
+ Slog.w(tag, "Unable to load animation resource", e);
+ return null;
+ }
+ }
+
+ public static Animation createHiddenByKeyguardExit(Context context,
+ LogDecelerateInterpolator interpolator, boolean onWallpaper,
+ boolean goingToNotificationShade, boolean subtleAnimation) {
+ if (goingToNotificationShade) {
+ return AnimationUtils.loadAnimation(context, R.anim.lock_screen_behind_enter_fade_in);
+ }
+
+ final int resource;
+ if (subtleAnimation) {
+ resource = R.anim.lock_screen_behind_enter_subtle;
+ } else if (onWallpaper) {
+ resource = R.anim.lock_screen_behind_enter_wallpaper;
+ } else {
+ resource = R.anim.lock_screen_behind_enter;
+ }
+
+ AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(context, resource);
+
+ // TODO: Use XML interpolators when we have log interpolators available in XML.
+ final List<Animation> animations = set.getAnimations();
+ for (int i = animations.size() - 1; i >= 0; --i) {
+ animations.get(i).setInterpolator(interpolator);
+ }
+
+ return set;
+ }
+}
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 892c5a53527b..50bbfc5ccb08 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -91,11 +91,12 @@ interface IInputMethodManager {
/** Remove the IME surface. Requires passing the currently focused window. */
oneway void removeImeSurfaceFromWindow(in IBinder windowToken,
in IVoidResultCallback resultCallback);
- void startProtoDump(in byte[] protoDump, int source, String where);
+ oneway void startProtoDump(in byte[] protoDump, int source, String where,
+ in IVoidResultCallback resultCallback);
oneway void isImeTraceEnabled(in IBooleanResultCallback resultCallback);
// Starts an ime trace.
- void startImeTrace();
+ oneway void startImeTrace(in IVoidResultCallback resultCallback);
// Stops an ime trace.
- void stopImeTrace();
+ oneway void stopImeTrace(in IVoidResultCallback resultCallback);
}
diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp
index 4eaa016df6f2..9cc72437a023 100644
--- a/core/jni/android_view_InputDevice.cpp
+++ b/core/jni/android_view_InputDevice.cpp
@@ -70,7 +70,8 @@ jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& devi
deviceInfo.isExternal(), deviceInfo.getSources(),
deviceInfo.getKeyboardType(), kcmObj.get(),
deviceInfo.hasVibrator(), hasMic,
- deviceInfo.hasButtonUnderPad(), deviceInfo.hasSensor()));
+ deviceInfo.hasButtonUnderPad(), deviceInfo.hasSensor(),
+ deviceInfo.hasBattery()));
const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
for (const InputDeviceInfo::MotionRange& range: ranges) {
@@ -90,9 +91,10 @@ int register_android_view_InputDevice(JNIEnv* env)
gInputDeviceClassInfo.clazz = FindClassOrDie(env, "android/view/InputDevice");
gInputDeviceClassInfo.clazz = MakeGlobalRefOrDie(env, gInputDeviceClassInfo.clazz);
- gInputDeviceClassInfo.ctor = GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz, "<init>",
- "(IIILjava/lang/String;IILjava/lang/"
- "String;ZIILandroid/view/KeyCharacterMap;ZZZZ)V");
+ gInputDeviceClassInfo.ctor =
+ GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz, "<init>",
+ "(IIILjava/lang/String;IILjava/lang/"
+ "String;ZIILandroid/view/KeyCharacterMap;ZZZZZ)V");
gInputDeviceClassInfo.addMotionRange = GetMethodIDOrDie(env, gInputDeviceClassInfo.clazz,
"addMotionRange", "(IIFFFFF)V");
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 4ef63ae93016..05fcaec82f84 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -27,6 +27,7 @@
#include <android-base/chrono_utils.h>
#include <android/graphics/region.h>
#include <android/gui/BnScreenCaptureListener.h>
+#include <android/os/IInputConstants.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/android_hardware_HardwareBuffer.h>
#include <android_runtime/android_view_Surface.h>
@@ -110,10 +111,12 @@ static struct {
static struct {
jfieldID pixelFormat;
jfieldID sourceCrop;
- jfieldID frameScale;
+ jfieldID frameScaleX;
+ jfieldID frameScaleY;
jfieldID captureSecureLayers;
jfieldID allowProtected;
jfieldID uid;
+ jfieldID grayscale;
} gCaptureArgsClassInfo;
static struct {
@@ -380,13 +383,17 @@ static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs&
captureArgs.sourceCrop =
rectFromObj(env,
env->GetObjectField(captureArgsObject, gCaptureArgsClassInfo.sourceCrop));
- captureArgs.frameScale =
- env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScale);
+ captureArgs.frameScaleX =
+ env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScaleX);
+ captureArgs.frameScaleY =
+ env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScaleY);
captureArgs.captureSecureLayers =
env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers);
captureArgs.allowProtected =
env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.allowProtected);
captureArgs.uid = env->GetLongField(captureArgsObject, gCaptureArgsClassInfo.uid);
+ captureArgs.grayscale =
+ env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.grayscale);
}
static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env,
@@ -1619,7 +1626,8 @@ static void nativeSetFrameTimelineVsync(JNIEnv* env, jclass clazz, jlong transac
jlong frameTimelineVsyncId) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
- transaction->setFrameTimelineVsync(frameTimelineVsyncId);
+ transaction->setFrameTimelineInfo(
+ {frameTimelineVsyncId, android::os::IInputConstants::INVALID_INPUT_EVENT_ID});
}
class JankDataListenerWrapper : public JankDataListener {
@@ -2032,12 +2040,14 @@ int register_android_view_SurfaceControl(JNIEnv* env)
gCaptureArgsClassInfo.pixelFormat = GetFieldIDOrDie(env, captureArgsClazz, "mPixelFormat", "I");
gCaptureArgsClassInfo.sourceCrop =
GetFieldIDOrDie(env, captureArgsClazz, "mSourceCrop", "Landroid/graphics/Rect;");
- gCaptureArgsClassInfo.frameScale = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScale", "F");
+ gCaptureArgsClassInfo.frameScaleX = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScaleX", "F");
+ gCaptureArgsClassInfo.frameScaleY = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScaleY", "F");
gCaptureArgsClassInfo.captureSecureLayers =
GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z");
gCaptureArgsClassInfo.allowProtected =
GetFieldIDOrDie(env, captureArgsClazz, "mAllowProtected", "Z");
gCaptureArgsClassInfo.uid = GetFieldIDOrDie(env, captureArgsClazz, "mUid", "J");
+ gCaptureArgsClassInfo.grayscale = GetFieldIDOrDie(env, captureArgsClazz, "mGrayscale", "Z");
jclass displayCaptureArgsClazz =
FindClassOrDie(env, "android/view/SurfaceControl$DisplayCaptureArgs");
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index c76a5d3dd9fa..c5a955976867 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -70,7 +70,6 @@
#include <bionic/malloc.h>
#include <bionic/mte.h>
#include <cutils/fs.h>
-#include <cutils/memory.h>
#include <cutils/multiuser.h>
#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>
@@ -621,13 +620,6 @@ static void PreApplicationInit() {
// Set the jemalloc decay time to 1.
mallopt(M_DECAY_TIME, 1);
-
- // Avoid potentially expensive memory mitigations, mostly meant for system
- // processes, in apps. These may cause app compat problems, use more memory,
- // or reduce performance. While it would be nice to have them for apps,
- // we will have to wait until they are proven out, have more efficient
- // hardware, and/or apply them only to new applications.
- process_disable_memory_mitigations();
}
static void SetUpSeccompFilter(uid_t uid, bool is_child_zygote) {
@@ -1785,6 +1777,14 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
break;
}
mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, heap_tagging_level);
+
+ // Avoid heap zero initialization for applications without MTE. Zero init may
+ // cause app compat problems, use more memory, or reduce performance. While it
+ // would be nice to have them for apps, we will have to wait until they are
+ // proven out, have more efficient hardware, and/or apply them only to new
+ // applications.
+ mallopt(M_BIONIC_ZERO_INIT, 0);
+
// Now that we've used the flag, clear it so that we don't pass unknown flags to the ART runtime.
runtime_flags &= ~RuntimeFlags::MEMORY_TAG_LEVEL_MASK;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4acdb1663403..f447cd205516 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5168,6 +5168,11 @@
<permission android:name="android.permission.MANAGE_SEARCH_UI"
android:protectionLevel="signature" />
+ <!-- @SystemApi Allows an application to manage the smartspace service.
+ @hide <p>Not for use by third-party applications.</p> -->
+ <permission android:name="android.permission.MANAGE_SMARTSPACE"
+ android:protectionLevel="signature" />
+
<!-- Allows an app to set the theme overlay in /vendor/overlay
being used.
@hide <p>Not for use by third-party applications.</p> -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5e0cda69911b..01b8efafa2fd 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3800,6 +3800,15 @@
-->
<string name="config_defaultSearchUiService" translatable="false"></string>
+ <!-- The package name for the system's smartspace service.
+ This service returns smartspace results.
+
+ This service must be trusted, as it can be activated without explicit consent of the user.
+ If no service with the specified name exists on the device, smartspace will be disabled.
+ Example: "com.android.intelligence/.SmartspaceService"
+-->
+ <string name="config_defaultSmartspaceService" translatable="false"></string>
+
<!-- The package name for the system's speech recognition service.
This service must be trusted, as it can be activated without explicit consent of the user.
Example: "com.android.speech/.RecognitionService"
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index dfccdf4bd9a5..815330ff1851 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3498,6 +3498,7 @@
<java-symbol type="string" name="config_defaultAppPredictionService" />
<java-symbol type="string" name="config_defaultContentSuggestionsService" />
<java-symbol type="string" name="config_defaultSearchUiService" />
+ <java-symbol type="string" name="config_defaultSmartspaceService" />
<java-symbol type="string" name="config_defaultMusicRecognitionService" />
<java-symbol type="string" name="config_defaultAttentionService" />
<java-symbol type="string" name="config_defaultRotationResolverService" />
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index bb826deb4eff..151a320494b4 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -35,6 +35,8 @@
android:label="@string/permlab_testDenied"
android:description="@string/permdesc_testDenied" />
+ <uses-permission android:name="com.android.frameworks.coretests.permission.TEST_GRANTED" />
+
<uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED" />
@@ -76,7 +78,6 @@
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SMS"/>
- <uses-permission android:name="android.permission.TEST_GRANTED" />
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
<uses-permission android:name="com.google.android.googleapps.permission.ACCESS_GOOGLE_PASSWORD" />
<uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH" />
@@ -1455,6 +1456,7 @@
</intent-filter>
</receiver>
<receiver android:name="android.app.activity.RemoteGrantedReceiver"
+ android:process=":remoteReceiver"
android:permission="com.android.frameworks.coretests.permission.TEST_GRANTED"
android:exported="true">
<intent-filter android:priority="2">
@@ -1462,6 +1464,7 @@
</intent-filter>
</receiver>
<receiver android:name="android.app.activity.RemoteDeniedReceiver"
+ android:process=":remoteReceiver"
android:permission="com.android.frameworks.coretests.permission.TEST_DENIED"
android:exported="true">
<intent-filter android:priority="2">
diff --git a/core/tests/coretests/src/android/app/activity/BroadcastTest.java b/core/tests/coretests/src/android/app/activity/BroadcastTest.java
index 0f81896692c0..d79c2fe19ce2 100644
--- a/core/tests/coretests/src/android/app/activity/BroadcastTest.java
+++ b/core/tests/coretests/src/android/app/activity/BroadcastTest.java
@@ -56,6 +56,8 @@ public class BroadcastTest extends ActivityTestsBase {
"com.android.frameworks.coretests.activity.BROADCAST_MULTI";
public static final String BROADCAST_ABORT =
"com.android.frameworks.coretests.activity.BROADCAST_ABORT";
+ public static final String BROADCAST_RESULT =
+ "com.android.frameworks.coretests.activity.BROADCAST_RESULT";
public static final String BROADCAST_STICKY1 =
"com.android.frameworks.coretests.activity.BROADCAST_STICKY1";
@@ -106,7 +108,14 @@ public class BroadcastTest extends ActivityTestsBase {
}
public Intent makeBroadcastIntent(String action) {
+ return makeBroadcastIntent(action, false);
+ }
+
+ public Intent makeBroadcastIntent(String action, boolean makeImplicit) {
Intent intent = new Intent(action, null);
+ if (makeImplicit) {
+ intent.addFlags(intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ }
intent.putExtra("caller", mCallTarget);
return intent;
}
@@ -277,7 +286,7 @@ public class BroadcastTest extends ActivityTestsBase {
map.putString("foo", "you");
map.putString("remove", "me");
getContext().sendOrderedBroadcast(
- new Intent("com.android.frameworks.coretests.activity.BROADCAST_RESULT"),
+ makeBroadcastIntent(BROADCAST_RESULT, true),
null, broadcastReceiver, null, 1, "foo", map);
while (!broadcastReceiver.mHaveResult) {
try {
@@ -424,10 +433,13 @@ public class BroadcastTest extends ActivityTestsBase {
public void testLocalReceivePermissionGranted() throws Exception {
setExpectedReceivers(new String[]{RECEIVER_LOCAL});
- getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL_GRANTED));
+ getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL_GRANTED, true));
waitForResultOrThrow(BROADCAST_TIMEOUT);
}
+ /*
+ // TODO: multi-package test b/c self-target broadcasts are always allowed
+ // even when gated on ungranted permissions
public void testLocalReceivePermissionDenied() throws Exception {
setExpectedReceivers(new String[]{RECEIVER_RESULTS});
@@ -438,16 +450,17 @@ public class BroadcastTest extends ActivityTestsBase {
};
getContext().sendOrderedBroadcast(
- makeBroadcastIntent(BROADCAST_LOCAL_DENIED),
+ makeBroadcastIntent(BROADCAST_LOCAL_DENIED, true),
null, finish, null, Activity.RESULT_CANCELED,
null, null);
waitForResultOrThrow(BROADCAST_TIMEOUT);
}
+ */
public void testLocalBroadcastPermissionGranted() throws Exception {
setExpectedReceivers(new String[]{RECEIVER_LOCAL});
getContext().sendBroadcast(
- makeBroadcastIntent(BROADCAST_LOCAL),
+ makeBroadcastIntent(BROADCAST_LOCAL, true),
PERMISSION_GRANTED);
waitForResultOrThrow(BROADCAST_TIMEOUT);
}
@@ -462,7 +475,7 @@ public class BroadcastTest extends ActivityTestsBase {
};
getContext().sendOrderedBroadcast(
- makeBroadcastIntent(BROADCAST_LOCAL),
+ makeBroadcastIntent(BROADCAST_LOCAL, true),
PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
null, null);
waitForResultOrThrow(BROADCAST_TIMEOUT);
@@ -470,10 +483,13 @@ public class BroadcastTest extends ActivityTestsBase {
public void testRemoteReceivePermissionGranted() throws Exception {
setExpectedReceivers(new String[]{RECEIVER_REMOTE});
- getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE_GRANTED));
+ getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE_GRANTED, true));
waitForResultOrThrow(BROADCAST_TIMEOUT);
}
+ /*
+ // TODO: multi-package test b/c self-target broadcasts are always allowed
+ // even when gated on ungranted permissions
public void testRemoteReceivePermissionDenied() throws Exception {
setExpectedReceivers(new String[]{RECEIVER_RESULTS});
@@ -484,16 +500,17 @@ public class BroadcastTest extends ActivityTestsBase {
};
getContext().sendOrderedBroadcast(
- makeBroadcastIntent(BROADCAST_REMOTE_DENIED),
+ makeBroadcastIntent(BROADCAST_REMOTE_DENIED, true),
null, finish, null, Activity.RESULT_CANCELED,
null, null);
waitForResultOrThrow(BROADCAST_TIMEOUT);
}
+ */
public void testRemoteBroadcastPermissionGranted() throws Exception {
setExpectedReceivers(new String[]{RECEIVER_REMOTE});
getContext().sendBroadcast(
- makeBroadcastIntent(BROADCAST_REMOTE),
+ makeBroadcastIntent(BROADCAST_REMOTE, true),
PERMISSION_GRANTED);
waitForResultOrThrow(BROADCAST_TIMEOUT);
}
@@ -508,7 +525,7 @@ public class BroadcastTest extends ActivityTestsBase {
};
getContext().sendOrderedBroadcast(
- makeBroadcastIntent(BROADCAST_REMOTE),
+ makeBroadcastIntent(BROADCAST_REMOTE, true),
PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
null, null);
waitForResultOrThrow(BROADCAST_TIMEOUT);
@@ -516,13 +533,13 @@ public class BroadcastTest extends ActivityTestsBase {
public void testReceiverCanNotRegister() throws Exception {
setExpectedReceivers(new String[]{RECEIVER_LOCAL});
- getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_FAIL_REGISTER));
+ getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_FAIL_REGISTER, true));
waitForResultOrThrow(BROADCAST_TIMEOUT);
}
public void testReceiverCanNotBind() throws Exception {
setExpectedReceivers(new String[]{RECEIVER_LOCAL});
- getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_FAIL_BIND));
+ getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_FAIL_BIND, true));
waitForResultOrThrow(BROADCAST_TIMEOUT);
}
diff --git a/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java b/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java
index 766245600d13..0b21fa90c1c4 100644
--- a/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java
+++ b/core/tests/coretests/src/android/app/activity/LaunchpadActivity.java
@@ -253,16 +253,16 @@ public class LaunchpadActivity extends Activity {
sendBroadcast(makeBroadcastIntent(BROADCAST_REGISTERED));
} else if (BROADCAST_LOCAL.equals(action)) {
setExpectedReceivers(new String[]{RECEIVER_LOCAL});
- sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL));
+ sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL, true));
} else if (BROADCAST_REMOTE.equals(action)) {
setExpectedReceivers(new String[]{RECEIVER_REMOTE});
- sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE));
+ sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE, true));
} else if (BROADCAST_ALL.equals(action)) {
setExpectedReceivers(new String[]{
RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL});
registerMyReceiver(new IntentFilter(BROADCAST_ALL));
sCallingTest.addIntermediate("after-register");
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL, true), null);
} else if (BROADCAST_MULTI.equals(action)) {
setExpectedReceivers(new String[]{
RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
@@ -277,23 +277,26 @@ public class LaunchpadActivity extends Activity {
RECEIVER_REMOTE, RECEIVER_LOCAL});
registerMyReceiver(new IntentFilter(BROADCAST_ALL));
sCallingTest.addIntermediate("after-register");
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REPEAT), null);
+ final Intent allIntent = makeBroadcastIntent(BROADCAST_ALL, true);
+ final Intent localIntent = makeBroadcastIntent(BROADCAST_LOCAL, true);
+ final Intent remoteIntent = makeBroadcastIntent(BROADCAST_REMOTE, true);
+ sendOrderedBroadcast(allIntent, null);
+ sendOrderedBroadcast(allIntent, null);
+ sendOrderedBroadcast(allIntent, null);
+ sendOrderedBroadcast(localIntent, null);
+ sendOrderedBroadcast(remoteIntent, null);
+ sendOrderedBroadcast(localIntent, null);
+ sendOrderedBroadcast(remoteIntent, null);
+ sendOrderedBroadcast(allIntent, null);
+ sendOrderedBroadcast(allIntent, null);
+ sendOrderedBroadcast(allIntent, null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REPEAT, true), null);
} else if (BROADCAST_ABORT.equals(action)) {
setExpectedReceivers(new String[]{
RECEIVER_REMOTE, RECEIVER_ABORT});
registerMyReceiver(new IntentFilter(BROADCAST_ABORT));
sCallingTest.addIntermediate("after-register");
- sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ABORT), null);
+ sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ABORT, true), null);
} else if (BROADCAST_STICKY1.equals(action)) {
setExpectedReceivers(new String[]{RECEIVER_REG});
setExpectedData(new String[]{DATA_1});
@@ -436,7 +439,14 @@ public class LaunchpadActivity extends Activity {
}
private Intent makeBroadcastIntent(String action) {
+ return makeBroadcastIntent(action, false);
+ }
+
+ private Intent makeBroadcastIntent(String action, boolean makeImplicit) {
Intent intent = new Intent(action, null);
+ if (makeImplicit) {
+ intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ }
intent.putExtra("caller", mCallTarget);
return intent;
}
diff --git a/core/tests/coretests/src/android/app/activity/LocalDeniedReceiver.java b/core/tests/coretests/src/android/app/activity/LocalDeniedReceiver.java
index 2120a1db463c..16ea73f30937 100644
--- a/core/tests/coretests/src/android/app/activity/LocalDeniedReceiver.java
+++ b/core/tests/coretests/src/android/app/activity/LocalDeniedReceiver.java
@@ -23,7 +23,7 @@ import android.os.RemoteException;
import android.os.IBinder;
import android.os.Parcel;
-class LocalDeniedReceiver extends BroadcastReceiver {
+public class LocalDeniedReceiver extends BroadcastReceiver {
public LocalDeniedReceiver() {
}
diff --git a/core/tests/coretests/src/android/app/activity/RemoteDeniedReceiver.java b/core/tests/coretests/src/android/app/activity/RemoteDeniedReceiver.java
index 7c89346e820d..5c1ded93e1c3 100644
--- a/core/tests/coretests/src/android/app/activity/RemoteDeniedReceiver.java
+++ b/core/tests/coretests/src/android/app/activity/RemoteDeniedReceiver.java
@@ -23,7 +23,7 @@ import android.os.RemoteException;
import android.os.IBinder;
import android.os.Parcel;
-class RemoteDeniedReceiver extends BroadcastReceiver {
+public class RemoteDeniedReceiver extends BroadcastReceiver {
public RemoteDeniedReceiver() {
}
diff --git a/core/tests/coretests/src/android/content/pm/SignatureTest.java b/core/tests/coretests/src/android/content/pm/SignatureTest.java
index f0b4af6fc44f..19458da796e8 100644
--- a/core/tests/coretests/src/android/content/pm/SignatureTest.java
+++ b/core/tests/coretests/src/android/content/pm/SignatureTest.java
@@ -54,6 +54,32 @@ public class SignatureTest extends TestCase {
assertFalse(Signature.areEffectiveMatch(asArray(A, M), asArray(A, B)));
}
+ public void testHashCode_doesNotIncludeFlags() throws Exception {
+ // Some classes rely on the hash code not including the flags / capabilities for the signer
+ // to verify Set membership. This test verifies two signers with the same signature but
+ // different flags have the same hash code.
+ Signature signatureAWithAllCaps = new Signature(A.toCharsString());
+ // There are currently 5 capabilities that can be assigned to a previous signer, although
+ // for the purposes of this test all that matters is that the two flag values are distinct.
+ signatureAWithAllCaps.setFlags(31);
+ Signature signatureAWithNoCaps = new Signature(A.toCharsString());
+ signatureAWithNoCaps.setFlags(0);
+
+ assertEquals(signatureAWithAllCaps.hashCode(), signatureAWithNoCaps.hashCode());
+ }
+
+ public void testEquals_doesNotIncludeFlags() throws Exception {
+ // Similar to above some classes rely on equals only comparing the signature arrays
+ // for equality without including the flags. This test verifies two signers with the
+ // same signature but different flags are still considered equal.
+ Signature signatureAWithAllCaps = new Signature(A.toCharsString());
+ signatureAWithAllCaps.setFlags(31);
+ Signature signatureAWithNoCaps = new Signature(A.toCharsString());
+ signatureAWithNoCaps.setFlags(0);
+
+ assertEquals(signatureAWithAllCaps, signatureAWithNoCaps);
+ }
+
private static Signature[] asArray(Signature... s) {
return s;
}
diff --git a/core/tests/coretests/src/android/hardware/input/InputDeviceSensorManagerTest.java b/core/tests/coretests/src/android/hardware/input/InputDeviceSensorManagerTest.java
index b319886ae466..341ee37aee39 100644
--- a/core/tests/coretests/src/android/hardware/input/InputDeviceSensorManagerTest.java
+++ b/core/tests/coretests/src/android/hardware/input/InputDeviceSensorManagerTest.java
@@ -149,7 +149,7 @@ public class InputDeviceSensorManagerTest {
0 /* vendorId */, 0 /* productId */, "descriptor", true /* isExternal */,
0 /* sources */, 0 /* keyboardType */, null /* keyCharacterMap */,
false /* hasVibrator */, false /* hasMicrophone */, false /* hasButtonUnderpad */,
- true /* hasSensor */);
+ true /* hasSensor */, false /* hasBattery */);
assertTrue(d.hasSensor());
return d;
}
diff --git a/core/tests/overlaytests/device/AndroidTest.xml b/core/tests/overlaytests/device/AndroidTest.xml
index ebbdda559ed2..2d7d9b450c8c 100644
--- a/core/tests/overlaytests/device/AndroidTest.xml
+++ b/core/tests/overlaytests/device/AndroidTest.xml
@@ -19,17 +19,13 @@
<option name="test-suite-tag" value="apct" />
<option name="test-suite-tag" value="apct-instrumentation" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
<option name="remount-system" value="true" />
<option name="push" value="OverlayDeviceTests.apk->/system/app/OverlayDeviceTests.apk" />
</target_preparer>
-
- <!-- Reboot to have the test APK scanned by PM and reboot after to remove the test APK. -->
- <target_preparer class="com.android.tradefed.targetprep.RebootTargetPreparer">
- <option name="pre-reboot" value="true" />
- <option name="post-reboot" value="true" />
- </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RebootTargetPreparer" />
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="cleanup-apks" value="true" />
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index c1310a9214e0..4a92cf11fa5c 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -693,6 +693,32 @@ public final class RenderNode {
throw new IllegalArgumentException("Unrecognized outline?");
}
+ /** @hide */
+ public boolean clearStretch() {
+ return nClearStretch(mNativeRenderNode);
+ }
+
+ /** @hide */
+ public boolean stretch(float left, float top, float right, float bottom,
+ float vecX, float vecY, float maxStretchAmount) {
+ if (1.0 < vecX || vecX < -1.0) {
+ throw new IllegalArgumentException("vecX must be in the range [-1, 1], was " + vecX);
+ }
+ if (1.0 < vecY || vecY < -1.0) {
+ throw new IllegalArgumentException("vecY must be in the range [-1, 1], was " + vecY);
+ }
+ if (top <= bottom || right <= left) {
+ throw new IllegalArgumentException(
+ "Stretch region must not be empty, got "
+ + new RectF(left, top, right, bottom).toString());
+ }
+ if (maxStretchAmount <= 0.0f) {
+ throw new IllegalArgumentException(
+ "The max stretch amount must be >0, got " + maxStretchAmount);
+ }
+ return nStretch(mNativeRenderNode, left, top, right, bottom, vecX, vecY, maxStretchAmount);
+ }
+
/**
* Checks if the RenderNode has a shadow. That is, if the combination of {@link #getElevation()}
* and {@link #getTranslationZ()} is greater than zero, there is an {@link Outline} set with
@@ -1638,6 +1664,13 @@ public final class RenderNode {
private static native boolean nSetOutlineNone(long renderNode);
@CriticalNative
+ private static native boolean nClearStretch(long renderNode);
+
+ @CriticalNative
+ private static native boolean nStretch(long renderNode, float left, float top, float right,
+ float bottom, float vecX, float vecY, float maxStretch);
+
+ @CriticalNative
private static native boolean nHasShadow(long renderNode);
@CriticalNative
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index 164bc8669525..75ac61a22cab 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -363,6 +363,11 @@ public class AndroidKeyStoreProvider extends Provider {
}
}
+ if (response.iSecurityLevel == null) {
+ // This seems to be a pure certificate entry, nothing to return here.
+ return null;
+ }
+
Integer keymasterAlgorithm = null;
// We just need one digest for the algorithm name
int keymasterDigest = -1;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
index 5e7f6482ebed..07169cedc1d9 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
@@ -490,7 +490,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
int[] keymasterEncryptionPaddings =
KeyProperties.EncryptionPadding.allToKeymaster(
spec.getEncryptionPaddings());
- if (((spec.getPurposes() & KeyProperties.PURPOSE_DECRYPT) != 0)
+ if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0)
&& (spec.isRandomizedEncryptionRequired())) {
for (int keymasterPadding : keymasterEncryptionPaddings) {
if (!KeymasterUtils
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 122f91720bbd..ffeabd876b81 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -49,6 +49,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.Executor;
/**
* Encapsulates the data and UI elements of a bubble.
@@ -58,6 +59,7 @@ public class Bubble implements BubbleViewProvider {
private static final String TAG = "Bubble";
private final String mKey;
+ private final Executor mMainExecutor;
private long mLastUpdated;
private long mLastAccessed;
@@ -156,7 +158,8 @@ public class Bubble implements BubbleViewProvider {
* Note: Currently this is only being used when the bubble is persisted to disk.
*/
Bubble(@NonNull final String key, @NonNull final ShortcutInfo shortcutInfo,
- final int desiredHeight, final int desiredHeightResId, @Nullable final String title) {
+ final int desiredHeight, final int desiredHeightResId, @Nullable final String title,
+ Executor mainExecutor) {
Objects.requireNonNull(key);
Objects.requireNonNull(shortcutInfo);
mMetadataShortcutId = shortcutInfo.getId();
@@ -170,20 +173,25 @@ public class Bubble implements BubbleViewProvider {
mDesiredHeightResId = desiredHeightResId;
mTitle = title;
mShowBubbleUpdateDot = false;
+ mMainExecutor = mainExecutor;
}
@VisibleForTesting(visibility = PRIVATE)
Bubble(@NonNull final BubbleEntry entry,
@Nullable final Bubbles.NotificationSuppressionChangedListener listener,
- final Bubbles.PendingIntentCanceledListener intentCancelListener) {
+ final Bubbles.PendingIntentCanceledListener intentCancelListener,
+ Executor mainExecutor) {
mKey = entry.getKey();
mSuppressionListener = listener;
mIntentCancelListener = intent -> {
if (mIntent != null) {
mIntent.unregisterCancelListener(mIntentCancelListener);
}
- intentCancelListener.onPendingIntentCanceled(this);
+ mainExecutor.execute(() -> {
+ intentCancelListener.onPendingIntentCanceled(this);
+ });
};
+ mMainExecutor = mainExecutor;
setEntry(entry);
}
@@ -329,7 +337,8 @@ public class Bubble implements BubbleViewProvider {
stackView,
iconFactory,
skipInflation,
- callback);
+ callback,
+ mMainExecutor);
if (mInflateSynchronously) {
mInflationTask.onPostExecute(mInflationTask.doInBackground());
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 9419b9c6d344..7538c8b7ffad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -28,6 +28,16 @@ import static com.android.wm.shell.bubbles.BubblePositioner.TASKBAR_POSITION_BOT
import static com.android.wm.shell.bubbles.BubblePositioner.TASKBAR_POSITION_LEFT;
import static com.android.wm.shell.bubbles.BubblePositioner.TASKBAR_POSITION_NONE;
import static com.android.wm.shell.bubbles.BubblePositioner.TASKBAR_POSITION_RIGHT;
+import static com.android.wm.shell.bubbles.Bubbles.DISMISS_AGED;
+import static com.android.wm.shell.bubbles.Bubbles.DISMISS_BLOCKED;
+import static com.android.wm.shell.bubbles.Bubbles.DISMISS_GROUP_CANCELLED;
+import static com.android.wm.shell.bubbles.Bubbles.DISMISS_INVALID_INTENT;
+import static com.android.wm.shell.bubbles.Bubbles.DISMISS_NOTIF_CANCEL;
+import static com.android.wm.shell.bubbles.Bubbles.DISMISS_NO_BUBBLE_UP;
+import static com.android.wm.shell.bubbles.Bubbles.DISMISS_NO_LONGER_BUBBLE;
+import static com.android.wm.shell.bubbles.Bubbles.DISMISS_PACKAGE_REMOVED;
+import static com.android.wm.shell.bubbles.Bubbles.DISMISS_SHORTCUT_REMOVED;
+import static com.android.wm.shell.bubbles.Bubbles.DISMISS_USER_CHANGED;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
@@ -45,6 +55,8 @@ import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
@@ -53,6 +65,7 @@ import android.service.notification.NotificationListenerService.RankingMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
+import android.util.Slog;
import android.util.SparseSetArray;
import android.view.View;
import android.view.ViewGroup;
@@ -75,6 +88,9 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
import java.util.function.IntConsumer;
/**
@@ -83,7 +99,7 @@ import java.util.function.IntConsumer;
*
* The controller manages addition, removal, and visible state of bubbles on screen.
*/
-public class BubbleController implements Bubbles {
+public class BubbleController {
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES;
@@ -101,7 +117,8 @@ public class BubbleController implements Bubbles {
public static final String BOTTOM_POSITION = "Bottom";
private final Context mContext;
- private BubbleExpandListener mExpandListener;
+ private final BubblesImpl mImpl = new BubblesImpl();
+ private Bubbles.BubbleExpandListener mExpandListener;
@Nullable private BubbleStackView.SurfaceSynchronizer mSurfaceSynchronizer;
private final FloatingContentCoordinator mFloatingContentCoordinator;
private final BubbleDataRepository mDataRepository;
@@ -111,7 +128,7 @@ public class BubbleController implements Bubbles {
@Nullable private BubbleStackView mStackView;
private BubbleIconFactory mBubbleIconFactory;
private BubblePositioner mBubblePositioner;
- private SysuiProxy mSysuiProxy;
+ private Bubbles.SysuiProxy mSysuiProxy;
// Tracks the id of the current (foreground) user.
private int mCurrentUserId;
@@ -177,7 +194,7 @@ public class BubbleController implements Bubbles {
/**
* Injected constructor.
*/
- public static BubbleController create(Context context,
+ public static Bubbles create(Context context,
@Nullable BubbleStackView.SurfaceSynchronizer synchronizer,
FloatingContentCoordinator floatingContentCoordinator,
@Nullable IStatusBarService statusBarService,
@@ -186,14 +203,15 @@ public class BubbleController implements Bubbles {
LauncherApps launcherApps,
UiEventLogger uiEventLogger,
ShellTaskOrganizer organizer,
- ShellExecutor mainExecutor) {
+ ShellExecutor mainExecutor,
+ Handler mainHandler) {
BubbleLogger logger = new BubbleLogger(uiEventLogger);
BubblePositioner positioner = new BubblePositioner(context, windowManager);
- BubbleData data = new BubbleData(context, logger, positioner);
+ BubbleData data = new BubbleData(context, logger, positioner, mainExecutor);
return new BubbleController(context, data, synchronizer, floatingContentCoordinator,
- new BubbleDataRepository(context, launcherApps),
+ new BubbleDataRepository(context, launcherApps, mainExecutor),
statusBarService, windowManager, windowManagerShellWrapper, launcherApps,
- logger, organizer, positioner, mainExecutor);
+ logger, organizer, positioner, mainExecutor, mainHandler).mImpl;
}
/**
@@ -212,7 +230,8 @@ public class BubbleController implements Bubbles {
BubbleLogger bubbleLogger,
ShellTaskOrganizer organizer,
BubblePositioner positioner,
- ShellExecutor mainExecutor) {
+ ShellExecutor mainExecutor,
+ Handler mainHandler) {
mContext = context;
mFloatingContentCoordinator = floatingContentCoordinator;
mDataRepository = dataRepository;
@@ -299,7 +318,12 @@ public class BubbleController implements Bubbles {
mBubbleData.removeBubblesWithInvalidShortcuts(
packageName, validShortcuts, DISMISS_SHORTCUT_REMOVED);
}
- });
+ }, mainHandler);
+ }
+
+ @VisibleForTesting
+ public Bubbles getImpl() {
+ return mImpl;
}
/**
@@ -313,8 +337,7 @@ public class BubbleController implements Bubbles {
}
}
- @Override
- public void openBubbleOverflow() {
+ private void openBubbleOverflow() {
ensureStackViewCreated();
mBubbleData.setShowingOverflow(true);
mBubbleData.setSelectedBubble(mBubbleData.getOverflow());
@@ -322,8 +345,7 @@ public class BubbleController implements Bubbles {
}
/** Called when any taskbar state changes (e.g. visibility, position, sizes). */
- @Override
- public void onTaskbarChanged(Bundle b) {
+ private void onTaskbarChanged(Bundle b) {
if (b == null) {
return;
}
@@ -371,8 +393,7 @@ public class BubbleController implements Bubbles {
* Called when the status bar has become visible or invisible (either permanently or
* temporarily).
*/
- @Override
- public void onStatusBarVisibilityChanged(boolean visible) {
+ private void onStatusBarVisibilityChanged(boolean visible) {
if (mStackView != null) {
// Hide the stack temporarily if the status bar has been made invisible, and the stack
// is collapsed. An expanded stack should remain visible until collapsed.
@@ -380,15 +401,13 @@ public class BubbleController implements Bubbles {
}
}
- @Override
- public void onZenStateChanged() {
+ private void onZenStateChanged() {
for (Bubble b : mBubbleData.getBubbles()) {
b.setShowDot(b.showInShade());
}
}
- @Override
- public void onStatusBarStateChanged(boolean isShade) {
+ private void onStatusBarStateChanged(boolean isShade) {
mIsStatusBarShade = isShade;
if (!mIsStatusBarShade) {
collapseStack();
@@ -402,8 +421,7 @@ public class BubbleController implements Bubbles {
updateStack();
}
- @Override
- public void onUserChanged(int newUserId) {
+ private void onUserChanged(int newUserId) {
saveBubbles(mCurrentUserId);
mBubbleData.dismissAll(DISMISS_USER_CHANGED);
restoreBubbles(newUserId);
@@ -442,7 +460,7 @@ public class BubbleController implements Bubbles {
return mBubblePositioner;
}
- SysuiProxy getSysuiProxy() {
+ Bubbles.SysuiProxy getSysuiProxy() {
return mSysuiProxy;
}
@@ -453,7 +471,8 @@ public class BubbleController implements Bubbles {
private void ensureStackViewCreated() {
if (mStackView == null) {
mStackView = new BubbleStackView(
- mContext, this, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator);
+ mContext, this, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator,
+ mMainExecutor);
mStackView.onOrientationChanged();
if (mExpandListener != null) {
mStackView.setExpandListener(mExpandListener);
@@ -576,8 +595,7 @@ public class BubbleController implements Bubbles {
mSavedBubbleKeysPerUser.remove(mCurrentUserId);
}
- @Override
- public void updateForThemeChanges() {
+ private void updateForThemeChanges() {
if (mStackView != null) {
mStackView.onThemeChanged();
}
@@ -593,8 +611,7 @@ public class BubbleController implements Bubbles {
}
}
- @Override
- public void onConfigChanged(Configuration newConfig) {
+ private void onConfigChanged(Configuration newConfig) {
if (mBubblePositioner != null) {
// This doesn't trigger any changes, always update it
mBubblePositioner.update(newConfig.orientation);
@@ -620,18 +637,19 @@ public class BubbleController implements Bubbles {
}
}
- @Override
- public void setBubbleScrim(View view) {
+ private void setBubbleScrim(View view, BiConsumer<Executor, Looper> callback) {
mBubbleScrim = view;
+ callback.accept(mMainExecutor, mMainExecutor.executeBlockingForResult(() -> {
+ return Looper.myLooper();
+ }, Looper.class));
}
- @Override
- public void setSysuiProxy(SysuiProxy proxy) {
+ private void setSysuiProxy(Bubbles.SysuiProxy proxy) {
mSysuiProxy = proxy;
}
- @Override
- public void setExpandListener(BubbleExpandListener listener) {
+ @VisibleForTesting
+ public void setExpandListener(Bubbles.BubbleExpandListener listener) {
mExpandListener = ((isExpanding, key) -> {
if (listener != null) {
listener.onBubbleExpandChanged(isExpanding, key);
@@ -654,17 +672,17 @@ public class BubbleController implements Bubbles {
return mBubbleData.hasBubbles() || mBubbleData.isShowingOverflow();
}
- @Override
+ @VisibleForTesting
public boolean isStackExpanded() {
return mBubbleData.isExpanded();
}
- @Override
+ @VisibleForTesting
public void collapseStack() {
mBubbleData.setExpanded(false /* expanded */);
}
- @Override
+ @VisibleForTesting
public boolean isBubbleNotificationSuppressedFromShade(String key, String groupKey) {
boolean isSuppressedBubble = (mBubbleData.hasAnyBubbleWithKey(key)
&& !mBubbleData.getAnyBubbleWithkey(key).showInShade());
@@ -674,23 +692,19 @@ public class BubbleController implements Bubbles {
return (isSummary && isSuppressedSummary) || isSuppressedBubble;
}
- @Override
- public boolean isSummarySuppressed(String groupKey) {
- return mBubbleData.isSummarySuppressed(groupKey);
- }
-
- @Override
- public void removeSuppressedSummary(String groupKey) {
- mBubbleData.removeSuppressedSummary(groupKey);
- }
-
- @Override
- public String getSummaryKey(String groupKey) {
- return mBubbleData.getSummaryKey(groupKey);
+ private void removeSuppressedSummaryIfNecessary(String groupKey, Consumer<String> callback,
+ Executor callbackExecutor) {
+ if (mBubbleData.isSummarySuppressed(groupKey)) {
+ mBubbleData.removeSuppressedSummary(groupKey);
+ if (callback != null) {
+ callbackExecutor.execute(() -> {
+ callback.accept(mBubbleData.getSummaryKey(groupKey));
+ });
+ }
+ }
}
- @Override
- public boolean isBubbleExpanded(String key) {
+ private boolean isBubbleExpanded(String key) {
return isStackExpanded() && mBubbleData != null && mBubbleData.getSelectedBubble() != null
&& mBubbleData.getSelectedBubble().getKey().equals(key);
}
@@ -704,7 +718,7 @@ public class BubbleController implements Bubbles {
setIsBubble(bubble, true /* isBubble */);
}
- @Override
+ @VisibleForTesting
public void expandStackAndSelectBubble(BubbleEntry entry) {
if (mIsStatusBarShade) {
mNotifEntryToExpandOnShadeUnlock = null;
@@ -809,15 +823,13 @@ public class BubbleController implements Bubbles {
}
}
- @Override
- public void onEntryAdded(BubbleEntry entry) {
+ private void onEntryAdded(BubbleEntry entry) {
if (canLaunchInActivityView(mContext, entry)) {
updateBubble(entry);
}
}
- @Override
- public void onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp) {
+ private void onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp) {
// shouldBubbleUp checks canBubble & for bubble metadata
boolean shouldBubble = shouldBubbleUp && canLaunchInActivityView(mContext, entry);
if (!shouldBubble && mBubbleData.hasAnyBubbleWithKey(entry.getKey())) {
@@ -828,8 +840,7 @@ public class BubbleController implements Bubbles {
}
}
- @Override
- public void onEntryRemoved(BubbleEntry entry) {
+ private void onEntryRemoved(BubbleEntry entry) {
if (isSummaryOfBubbles(entry)) {
final String groupKey = entry.getStatusBarNotification().getGroupKey();
mBubbleData.removeSuppressedSummary(groupKey);
@@ -844,8 +855,7 @@ public class BubbleController implements Bubbles {
}
}
- @Override
- public void onRankingUpdated(RankingMap rankingMap) {
+ private void onRankingUpdated(RankingMap rankingMap) {
if (mTmpRanking == null) {
mTmpRanking = new NotificationListenerService.Ranking();
}
@@ -882,6 +892,8 @@ public class BubbleController implements Bubbles {
return bubbleChildren;
}
for (Bubble bubble : mBubbleData.getActiveBubbles()) {
+ // TODO(178620678): Prevent calling into SysUI since this can be a part of a blocking
+ // call from SysUI to Shell
final BubbleEntry entry = mSysuiProxy.getPendingOrActiveEntry(bubble.getKey());
if (entry != null && groupKey.equals(entry.getStatusBarNotification().getGroupKey())) {
bubbleChildren.add(bubble);
@@ -951,7 +963,7 @@ public class BubbleController implements Bubbles {
ArrayList<Bubble> bubblesToBeRemovedFromRepository = new ArrayList<>();
for (Pair<Bubble, Integer> removed : removedBubbles) {
final Bubble bubble = removed.first;
- @DismissReason final int reason = removed.second;
+ @Bubbles.DismissReason final int reason = removed.second;
if (mStackView != null) {
mStackView.removeBubble(bubble);
@@ -1029,8 +1041,7 @@ public class BubbleController implements Bubbles {
}
};
- @Override
- public boolean handleDismissalInterception(BubbleEntry entry,
+ private boolean handleDismissalInterception(BubbleEntry entry,
@Nullable List<BubbleEntry> children, IntConsumer removeCallback) {
if (isSummaryOfBubbles(entry)) {
handleSummaryDismissalInterception(entry, children, removeCallback);
@@ -1137,8 +1148,7 @@ public class BubbleController implements Bubbles {
/**
* Description of current bubble state.
*/
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ private void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("BubbleController state:");
mBubbleData.dump(fd, pw, args);
pw.println();
@@ -1216,4 +1226,175 @@ public class BubbleController implements Bubbles {
}
}
}
+
+ private class BubblesImpl implements Bubbles {
+ @Override
+ public boolean isBubbleNotificationSuppressedFromShade(String key, String groupKey) {
+ return mMainExecutor.executeBlockingForResult(() -> {
+ return BubbleController.this.isBubbleNotificationSuppressedFromShade(key, groupKey);
+ }, Boolean.class);
+ }
+
+ @Override
+ public boolean isBubbleExpanded(String key) {
+ return mMainExecutor.executeBlockingForResult(() -> {
+ return BubbleController.this.isBubbleExpanded(key);
+ }, Boolean.class);
+ }
+
+ @Override
+ public boolean isStackExpanded() {
+ return mMainExecutor.executeBlockingForResult(() -> {
+ return BubbleController.this.isStackExpanded();
+ }, Boolean.class);
+ }
+
+ @Override
+ public void removeSuppressedSummaryIfNecessary(String groupKey, Consumer<String> callback,
+ Executor callbackExecutor) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.removeSuppressedSummaryIfNecessary(groupKey, callback,
+ callbackExecutor);
+ });
+ }
+
+ @Override
+ public void collapseStack() {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.collapseStack();
+ });
+ }
+
+ @Override
+ public void updateForThemeChanges() {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.updateForThemeChanges();
+ });
+ }
+
+ @Override
+ public void expandStackAndSelectBubble(BubbleEntry entry) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.expandStackAndSelectBubble(entry);
+ });
+ }
+
+ @Override
+ public void onTaskbarChanged(Bundle b) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.onTaskbarChanged(b);
+ });
+ }
+
+ @Override
+ public void openBubbleOverflow() {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.openBubbleOverflow();
+ });
+ }
+
+ @Override
+ public boolean handleDismissalInterception(BubbleEntry entry,
+ @Nullable List<BubbleEntry> children, IntConsumer removeCallback) {
+ return mMainExecutor.executeBlockingForResult(() -> {
+ return BubbleController.this.handleDismissalInterception(entry, children,
+ removeCallback);
+ }, Boolean.class);
+ }
+
+ @Override
+ public void setSysuiProxy(SysuiProxy proxy) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.setSysuiProxy(proxy);
+ });
+ }
+
+ @Override
+ public void setBubbleScrim(View view, BiConsumer<Executor, Looper> callback) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.setBubbleScrim(view, callback);
+ });
+ }
+
+ @Override
+ public void setExpandListener(BubbleExpandListener listener) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.setExpandListener(listener);
+ });
+ }
+
+ @Override
+ public void onEntryAdded(BubbleEntry entry) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.onEntryAdded(entry);
+ });
+ }
+
+ @Override
+ public void onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.onEntryUpdated(entry, shouldBubbleUp);
+ });
+ }
+
+ @Override
+ public void onEntryRemoved(BubbleEntry entry) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.onEntryRemoved(entry);
+ });
+ }
+
+ @Override
+ public void onRankingUpdated(RankingMap rankingMap) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.onRankingUpdated(rankingMap);
+ });
+ }
+
+ @Override
+ public void onStatusBarVisibilityChanged(boolean visible) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.onStatusBarVisibilityChanged(visible);
+ });
+ }
+
+ @Override
+ public void onZenStateChanged() {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.onZenStateChanged();
+ });
+ }
+
+ @Override
+ public void onStatusBarStateChanged(boolean isShade) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.onStatusBarStateChanged(isShade);
+ });
+ }
+
+ @Override
+ public void onUserChanged(int newUserId) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.onUserChanged(newUserId);
+ });
+ }
+
+ @Override
+ public void onConfigChanged(Configuration newConfig) {
+ mMainExecutor.execute(() -> {
+ BubbleController.this.onConfigChanged(newConfig);
+ });
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ try {
+ mMainExecutor.executeBlocking(() -> {
+ BubbleController.this.dump(fd, pw, args);
+ });
+ } catch (InterruptedException e) {
+ Slog.e(TAG, "Failed to dump BubbleController in 2s");
+ }
+ }
+ }
}
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 e24ff063b661..9d196ba32f8a 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
@@ -46,6 +46,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -117,6 +118,7 @@ public class BubbleData {
private final Context mContext;
private final BubblePositioner mPositioner;
+ private final Executor mMainExecutor;
/** Bubbles that are actively in the stack. */
private final List<Bubble> mBubbles;
/** Bubbles that aged out to overflow. */
@@ -155,10 +157,12 @@ public class BubbleData {
*/
private HashMap<String, String> mSuppressedGroupKeys = new HashMap<>();
- public BubbleData(Context context, BubbleLogger bubbleLogger, BubblePositioner positioner) {
+ public BubbleData(Context context, BubbleLogger bubbleLogger, BubblePositioner positioner,
+ Executor mainExecutor) {
mContext = context;
mLogger = bubbleLogger;
mPositioner = positioner;
+ mMainExecutor = mainExecutor;
mOverflow = new BubbleOverflow(context, positioner);
mBubbles = new ArrayList<>();
mOverflowBubbles = new ArrayList<>();
@@ -264,7 +268,8 @@ public class BubbleData {
bubbleToReturn = mPendingBubbles.get(key);
} else if (entry != null) {
// New bubble
- bubbleToReturn = new Bubble(entry, mSuppressionListener, mCancelledListener);
+ bubbleToReturn = new Bubble(entry, mSuppressionListener, mCancelledListener,
+ mMainExecutor);
} else {
// Persisted bubble being promoted
bubbleToReturn = persistedBubble;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
index fc565f17546d..3108b02cc010 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt
@@ -27,6 +27,8 @@ import android.util.Log
import com.android.wm.shell.bubbles.storage.BubbleEntity
import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
import com.android.wm.shell.bubbles.storage.BubbleVolatileRepository
+import com.android.wm.shell.common.ShellExecutor
+import com.android.wm.shell.common.annotations.ExternalThread
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -34,12 +36,12 @@ import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.launch
import kotlinx.coroutines.yield
-internal class BubbleDataRepository(context: Context, private val launcherApps: LauncherApps) {
+internal class BubbleDataRepository(context: Context, private val launcherApps: LauncherApps,
+ private val mainExecutor : ShellExecutor) {
private val volatileRepository = BubbleVolatileRepository(launcherApps)
private val persistentRepository = BubblePersistentRepository(context)
private val ioScope = CoroutineScope(Dispatchers.IO)
- private val uiScope = CoroutineScope(Dispatchers.Main)
private var job: Job? = null
/**
@@ -109,6 +111,8 @@ internal class BubbleDataRepository(context: Context, private val launcherApps:
/**
* Load bubbles from disk.
+ * @param cb The callback to be run after the bubbles are loaded. This callback is always made
+ * on the main thread of the hosting process.
*/
@SuppressLint("WrongConstant")
fun loadBubbles(cb: (List<Bubble>) -> Unit) = ioScope.launch {
@@ -163,10 +167,11 @@ internal class BubbleDataRepository(context: Context, private val launcherApps:
shortcutInfo,
entity.desiredHeight,
entity.desiredHeightResId,
- entity.title
+ entity.title,
+ mainExecutor
) }
}
- uiScope.launch { cb(bubbles) }
+ mainExecutor.execute { cb(bubbles) }
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index fac368677d12..af421facd72a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -79,6 +79,7 @@ import com.android.wm.shell.bubbles.animation.ExpandedAnimationController;
import com.android.wm.shell.bubbles.animation.PhysicsAnimationLayout;
import com.android.wm.shell.bubbles.animation.StackAnimationController;
import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
import java.io.FileDescriptor;
@@ -147,7 +148,7 @@ public class BubbleStackView extends FrameLayout
* Handler to use for all delayed animations - this way, we can easily cancel them before
* starting a new animation.
*/
- private final Handler mDelayedAnimationHandler = new Handler();
+ private final ShellExecutor mDelayedAnimationExecutor;
/**
* Interface to synchronize {@link View} state and the screen.
@@ -311,7 +312,7 @@ public class BubbleStackView extends FrameLayout
}
}
- private BubbleController.BubbleExpandListener mExpandListener;
+ private Bubbles.BubbleExpandListener mExpandListener;
/** Callback to run when we want to unbubble the given notification's conversation. */
private Consumer<String> mUnbubbleConversationCallback;
@@ -734,9 +735,11 @@ public class BubbleStackView extends FrameLayout
@SuppressLint("ClickableViewAccessibility")
public BubbleStackView(Context context, BubbleController bubbleController,
BubbleData data, @Nullable SurfaceSynchronizer synchronizer,
- FloatingContentCoordinator floatingContentCoordinator) {
+ FloatingContentCoordinator floatingContentCoordinator,
+ ShellExecutor mainExecutor) {
super(context);
+ mDelayedAnimationExecutor = mainExecutor;
mBubbleController = bubbleController;
mBubbleData = data;
@@ -1366,7 +1369,7 @@ public class BubbleStackView extends FrameLayout
/**
* Sets the listener to notify when the bubble stack is expanded.
*/
- public void setExpandListener(BubbleController.BubbleExpandListener listener) {
+ public void setExpandListener(Bubbles.BubbleExpandListener listener) {
mExpandListener = listener;
}
@@ -1734,7 +1737,7 @@ public class BubbleStackView extends FrameLayout
mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false);
}
- mDelayedAnimationHandler.postDelayed(() -> {
+ mDelayedAnimationExecutor.executeDelayed(() -> {
PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel();
PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
.spring(AnimatableScaleMatrix.SCALE_X,
@@ -1791,10 +1794,12 @@ public class BubbleStackView extends FrameLayout
final long startDelay =
(long) (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION * 0.6f);
- mDelayedAnimationHandler.postDelayed(() -> mExpandedAnimationController.collapseBackToStack(
- mStackAnimationController.getStackPositionAlongNearestHorizontalEdge()
- /* collapseTo */,
- () -> mBubbleContainer.setActiveController(mStackAnimationController)), startDelay);
+ mDelayedAnimationExecutor.executeDelayed(() -> {
+ mExpandedAnimationController.collapseBackToStack(
+ mStackAnimationController.getStackPositionAlongNearestHorizontalEdge()
+ /* collapseTo */,
+ () -> mBubbleContainer.setActiveController(mStackAnimationController));
+ }, startDelay);
if (mTaskbarScrim.getVisibility() == VISIBLE) {
mTaskbarScrim.animate().alpha(0f).start();
@@ -1945,7 +1950,7 @@ public class BubbleStackView extends FrameLayout
mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);
- mDelayedAnimationHandler.postDelayed(() -> {
+ mDelayedAnimationExecutor.executeDelayed(() -> {
if (!mIsExpanded) {
mIsBubbleSwitchAnimating = false;
return;
@@ -1978,7 +1983,7 @@ public class BubbleStackView extends FrameLayout
* animating flags for those animations.
*/
private void cancelDelayedExpandCollapseSwitchAnimations() {
- mDelayedAnimationHandler.removeCallbacksAndMessages(null);
+ mDelayedAnimationExecutor.removeAllCallbacks();
mIsExpansionAnimating = false;
mIsBubbleSwitchAnimating = false;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
index 0e7e92d9554a..c5a712e271e4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
@@ -46,6 +46,7 @@ import com.android.wm.shell.R;
import java.lang.ref.WeakReference;
import java.util.Objects;
+import java.util.concurrent.Executor;
/**
* Simple task to inflate views & load necessary info to display a bubble.
@@ -71,6 +72,7 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
private BubbleIconFactory mIconFactory;
private boolean mSkipInflation;
private Callback mCallback;
+ private Executor mMainExecutor;
/**
* Creates a task to load information for the provided {@link Bubble}. Once all info
@@ -82,7 +84,8 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
BubbleStackView stackView,
BubbleIconFactory factory,
boolean skipInflation,
- Callback c) {
+ Callback c,
+ Executor mainExecutor) {
mBubble = b;
mContext = new WeakReference<>(context);
mController = new WeakReference<>(controller);
@@ -90,6 +93,7 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
mIconFactory = factory;
mSkipInflation = skipInflation;
mCallback = c;
+ mMainExecutor = mainExecutor;
}
@Override
@@ -103,10 +107,12 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
if (isCancelled() || viewInfo == null) {
return;
}
- mBubble.setViewInfo(viewInfo);
- if (mCallback != null) {
- mCallback.onBubbleViewsReady(mBubble);
- }
+ mMainExecutor.execute(() -> {
+ mBubble.setViewInfo(viewInfo);
+ if (mCallback != null) {
+ mCallback.onBubbleViewsReady(mBubble);
+ }
+ });
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index fa5ac449cd54..6102147e4b53 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -23,6 +23,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.content.res.Configuration;
import android.os.Bundle;
+import android.os.Looper;
import android.service.notification.NotificationListenerService.RankingMap;
import android.util.ArraySet;
import android.view.View;
@@ -37,6 +38,9 @@ import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
import java.util.function.IntConsumer;
/**
@@ -86,13 +90,14 @@ public interface Bubbles {
/** @return {@code true} if stack of bubbles is expanded or not. */
boolean isStackExpanded();
- /** @return {@code true} if the summary for the provided group key is suppressed. */
- boolean isSummarySuppressed(String groupKey);
-
/**
- * Removes a group key indicating that summary for this group should no longer be suppressed.
+ * Removes a group key indicating that the summary for this group should no longer be
+ * suppressed.
+ *
+ * @param callback If removed, this callback will be called with the summary key of the group
*/
- void removeSuppressedSummary(String groupKey);
+ void removeSuppressedSummaryIfNecessary(String groupKey, Consumer<String> callback,
+ Executor callbackExecutor);
/** Tell the stack of bubbles to collapse. */
void collapseStack();
@@ -134,19 +139,16 @@ public interface Bubbles {
boolean handleDismissalInterception(BubbleEntry entry, @Nullable List<BubbleEntry> children,
IntConsumer removeCallback);
- /**
- * Retrieves the notif entry key of the summary associated with the provided group key.
- *
- * @param groupKey the group to look up
- * @return the key for the notification that is the summary of this group.
- */
- String getSummaryKey(String groupKey);
-
/** Set the proxy to commnuicate with SysUi side components. */
void setSysuiProxy(SysuiProxy proxy);
- /** Set the scrim view for bubbles. */
- void setBubbleScrim(View view);
+ /**
+ * Set the scrim view for bubbles.
+ *
+ * @param callback The callback made with the executor and the executor's looper that the view
+ * will be running on.
+ **/
+ void setBubbleScrim(View view, BiConsumer<Executor, Looper> callback);
/** Set a listener to be notified of bubble expand events. */
void setExpandListener(BubbleExpandListener listener);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt
index a1b0dbe0a6dd..cf0cefec401a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/RelativeTouchListener.kt
@@ -91,7 +91,6 @@ abstract class RelativeTouchListener : View.OnTouchListener {
private var touchSlop: Int = -1
private var movedEnough = false
- private val handler = Handler(Looper.myLooper()!!)
private var performedLongClick = false
@Suppress("UNCHECKED_CAST")
@@ -115,7 +114,7 @@ abstract class RelativeTouchListener : View.OnTouchListener {
viewPositionOnTouchDown.set(v.translationX, v.translationY)
performedLongClick = false
- handler.postDelayed({
+ v.handler.postDelayed({
if (v.isLongClickable) {
performedLongClick = v.performLongClick()
}
@@ -125,7 +124,7 @@ abstract class RelativeTouchListener : View.OnTouchListener {
MotionEvent.ACTION_MOVE -> {
if (!movedEnough && hypot(dx, dy) > touchSlop && !performedLongClick) {
movedEnough = true
- handler.removeCallbacksAndMessages(null)
+ v.handler.removeCallbacksAndMessages(null)
}
if (movedEnough) {
@@ -141,7 +140,7 @@ abstract class RelativeTouchListener : View.OnTouchListener {
} else if (!performedLongClick) {
v.performClick()
} else {
- handler.removeCallbacksAndMessages(null)
+ v.handler.removeCallbacksAndMessages(null)
}
velocityTracker.clear()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
index b736fb0b9895..6abc8f6dda89 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java
@@ -20,6 +20,7 @@ import android.os.Looper;
import android.os.SystemClock;
import android.os.Trace;
+import java.lang.reflect.Array;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -68,6 +69,26 @@ public interface ShellExecutor extends Executor {
}
/**
+ * Convenience method to execute the blocking call with a default timeout and returns a value.
+ * Waits indefinitely for a typed result from a call.
+ */
+ default <T> T executeBlockingForResult(Supplier<T> runnable, Class clazz) {
+ final T[] result = (T[]) Array.newInstance(clazz, 1);
+ final CountDownLatch latch = new CountDownLatch(1);
+ execute(() -> {
+ result[0] = runnable.get();
+ latch.countDown();
+ });
+ try {
+ latch.await();
+ return result[0];
+ } catch (InterruptedException e) {
+ return null;
+ }
+ }
+
+
+ /**
* See {@link android.os.Handler#postDelayed(Runnable, long)}.
*/
void executeDelayed(Runnable runnable, long delayMillis);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 128d13c2ce2e..bb6704333050 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -30,7 +30,6 @@ import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.os.Handler;
import android.provider.DeviceConfig;
import android.util.Log;
import android.util.Size;
@@ -847,11 +846,11 @@ public class PipTouchHandler {
&& mPipBoundsState.getBounds().height()
< mPipBoundsState.getMaxSize().y;
if (toExpand) {
+ mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
animateToMaximizedState(null);
} else {
- animateToMinimizedState();
+ animateToUnexpandedState(getUserResizeBounds());
}
- mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
} else {
// Expand to fullscreen if this is a double tap
// the PiP should be frozen until the transition ends
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt
index 564a418a1082..d25774935e86 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestCannotPairNonResizeableApps.kt
@@ -21,7 +21,6 @@ import android.platform.test.annotations.Presubmit
import android.os.SystemClock
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
@@ -46,10 +45,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class AppPairsTestCannotPairNonResizeableApps(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
@@ -83,9 +80,8 @@ class AppPairsTestCannotPairNonResizeableApps(
}
}
- return FlickerTestRunnerFactory(instrumentation,
- repetitions = AppPairsHelper.TEST_REPETITIONS)
- .buildTest(transition, testSpec)
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
+ transition, testSpec, repetitions = AppPairsHelper.TEST_REPETITIONS)
}
}
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
index f63eb1db4d5c..5cbfec638da5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestPairPrimaryAndSecondaryApps.kt
@@ -21,13 +21,12 @@ import android.os.SystemClock
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.buildTestTag
import com.android.server.wm.flicker.traces.layers.getVisibleBounds
-import com.android.wm.shell.flicker.FlickerTestBase
+import com.android.wm.shell.flicker.FlickerTestBase.Companion.APP_PAIR_SPLIT_DIVIDER
import com.android.wm.shell.flicker.appPairsDividerIsVisible
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import org.junit.FixMethodOrder
@@ -44,10 +43,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class AppPairsTestPairPrimaryAndSecondaryApps(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
@@ -67,8 +64,7 @@ class AppPairsTestPairPrimaryAndSecondaryApps(
layersTrace {
appPairsDividerIsVisible()
end("appsEndingBounds", enabled = false) {
- val dividerRegion = entry.getVisibleBounds(
- FlickerTestBase.APP_PAIR_SPLIT_DIVIDER)
+ val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER)
this.hasVisibleRegion(primaryApp.defaultWindowName,
appPairsHelper.getPrimaryBounds(dividerRegion))
.hasVisibleRegion(secondaryApp.defaultWindowName,
@@ -83,8 +79,8 @@ class AppPairsTestPairPrimaryAndSecondaryApps(
}
}
}
- return FlickerTestRunnerFactory(instrumentation,
- repetitions = AppPairsHelper.TEST_REPETITIONS).buildTest(transition, testSpec)
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation, transition,
+ testSpec, repetitions = AppPairsHelper.TEST_REPETITIONS)
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
index 731d99829b1d..f57a000a0ccb 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestUnpairPrimaryAndSecondaryApps.kt
@@ -21,13 +21,12 @@ import android.os.SystemClock
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.buildTestTag
import com.android.server.wm.flicker.traces.layers.getVisibleBounds
-import com.android.wm.shell.flicker.FlickerTestBase
+import com.android.wm.shell.flicker.FlickerTestBase.Companion.APP_PAIR_SPLIT_DIVIDER
import com.android.wm.shell.flicker.appPairsDividerIsInvisible
import com.android.wm.shell.flicker.helpers.AppPairsHelper
import org.junit.FixMethodOrder
@@ -44,10 +43,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class AppPairsTestUnpairPrimaryAndSecondaryApps(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object : AppPairsTransition(InstrumentationRegistry.getInstrumentation()) {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
@@ -72,8 +69,7 @@ class AppPairsTestUnpairPrimaryAndSecondaryApps(
layersTrace {
appPairsDividerIsInvisible()
start("appsStartingBounds", enabled = false) {
- val dividerRegion = entry.getVisibleBounds(
- FlickerTestBase.APP_PAIR_SPLIT_DIVIDER)
+ val dividerRegion = entry.getVisibleBounds(APP_PAIR_SPLIT_DIVIDER)
this.hasVisibleRegion(primaryApp.defaultWindowName,
appPairsHelper.getPrimaryBounds(dividerRegion))
.hasVisibleRegion(secondaryApp.defaultWindowName,
@@ -92,8 +88,8 @@ class AppPairsTestUnpairPrimaryAndSecondaryApps(
}
}
}
- return FlickerTestRunnerFactory(instrumentation,
- repetitions = AppPairsHelper.TEST_REPETITIONS).buildTest(transition, testSpec)
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation, transition,
+ testSpec, repetitions = AppPairsHelper.TEST_REPETITIONS)
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt
index da3450bf9ff6..7191e8e95590 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsInAppPairsMode.kt
@@ -22,7 +22,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
@@ -54,16 +53,13 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class RotateTwoLaunchedAppsInAppPairsMode(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object : RotateTwoLaunchedAppsTransition(
InstrumentationRegistry.getInstrumentation()) {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<Array<Any>> {
- val instrumentation = InstrumentationRegistry.getInstrumentation()
val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
withTestName {
buildTestTag("testRotateTwoLaunchedAppsInAppPairsMode", configuration)
@@ -96,10 +92,10 @@ class RotateTwoLaunchedAppsInAppPairsMode(
}
}
- return FlickerTestRunnerFactory(instrumentation,
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
+ transition, testSpec,
repetitions = SplitScreenHelper.TEST_REPETITIONS,
- supportedRotations = listOf(Surface.ROTATION_90, Surface.ROTATION_270)
- ).buildTest(transition, testSpec)
+ supportedRotations = listOf(Surface.ROTATION_90, Surface.ROTATION_270))
}
}
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt
index 05543fdb3445..19ca31fbee4a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/RotateTwoLaunchedAppsRotateAndEnterAppPairsMode.kt
@@ -22,7 +22,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
@@ -54,16 +53,13 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class RotateTwoLaunchedAppsRotateAndEnterAppPairsMode(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object : RotateTwoLaunchedAppsTransition(
InstrumentationRegistry.getInstrumentation()) {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<Array<Any>> {
- val instrumentation = InstrumentationRegistry.getInstrumentation()
val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
withTestName {
buildTestTag("testRotateAndEnterAppPairsMode", configuration)
@@ -96,10 +92,11 @@ class RotateTwoLaunchedAppsRotateAndEnterAppPairsMode(
}
}
- return FlickerTestRunnerFactory(instrumentation,
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
+ transition, testSpec,
repetitions = SplitScreenHelper.TEST_REPETITIONS,
supportedRotations = listOf(Surface.ROTATION_90, Surface.ROTATION_270)
- ).buildTest(transition, testSpec)
+ )
}
}
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottomTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottomTest.kt
index 4ddfb3ecdebc..a3b8673d93ed 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottomTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottomTest.kt
@@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.endRotation
@@ -48,10 +47,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class ExitLegacySplitScreenFromBottomTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
@@ -59,9 +56,9 @@ class ExitLegacySplitScreenFromBottomTest(
val instrumentation = InstrumentationRegistry.getInstrumentation()
val splitScreenApp = SplitScreenHelper.getPrimary(instrumentation)
// TODO(b/162923992) Use of multiple segments of flicker spec for testing
- return FlickerTestRunnerFactory(instrumentation,
- listOf(Surface.ROTATION_0, Surface.ROTATION_90))
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
+ supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)) {
+ configuration ->
withTestName {
buildTestTag("exitSplitScreenFromBottom", configuration)
}
@@ -87,6 +84,11 @@ class ExitLegacySplitScreenFromBottomTest(
transitions {
device.exitSplitScreenFromBottom()
}
+ assertions {
+ windowManagerTrace {
+ all("isNotEmpty") { isNotEmpty() }
+ }
+ }
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncherTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncherTest.kt
index 43a756585e3c..4dcbdfff8cd5 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncherTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncherTest.kt
@@ -21,7 +21,6 @@ import android.support.test.launcherhelper.LauncherStrategyFactory
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.endRotation
@@ -60,10 +59,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class LegacySplitScreenToLauncherTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
@@ -74,8 +71,8 @@ class LegacySplitScreenToLauncherTest(
val testApp = SimpleAppHelper(instrumentation)
// b/161435597 causes the test not to work on 90 degrees
- return FlickerTestRunnerFactory(instrumentation, listOf(Surface.ROTATION_0))
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
+ supportedRotations = listOf(Surface.ROTATION_0)) { configuration ->
withTestName {
buildTestTag("splitScreenToLauncher", configuration)
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreenTest.kt
index f6b07729c196..95c1c16385c4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreenTest.kt
@@ -25,7 +25,6 @@ import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import com.android.server.wm.flicker.DOCKED_STACK_DIVIDER
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.endRotation
@@ -69,10 +68,8 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 159096424)
class ResizeLegacySplitScreenTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
private const val sSimpleActivity = "SimpleActivity"
private const val sImeActivity = "ImeActivity"
@@ -86,9 +83,8 @@ class ResizeLegacySplitScreenTest(
val testAppTop = SimpleAppHelper(instrumentation)
val testAppBottom = ImeAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation,
- supportedRotations = listOf(Surface.ROTATION_0))
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
+ supportedRotations = listOf(Surface.ROTATION_0)) { configuration ->
withTestName {
val description = (startRatio.toString().replace("/", "-") + "_to_" +
stopRatio.toString().replace("/", "-"))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index 2ffc338f4f75..af62eb9ae40d 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -20,7 +20,6 @@ import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.helpers.buildTestTag
@@ -53,19 +52,16 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 152738416)
class EnterPipTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = PipAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation,
- supportedRotations = listOf(Surface.ROTATION_0))
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
+ supportedRotations = listOf(Surface.ROTATION_0)) { configuration ->
withTestName { buildTestTag("enterPip", testApp, configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index 4a6a5b504e2c..a00c5f463a50 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.endRotation
@@ -54,10 +53,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class PipRotationTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
@@ -65,9 +62,9 @@ class PipRotationTest(
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = FixedAppHelper(instrumentation)
val pipApp = PipAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation,
- listOf(Surface.ROTATION_0, Surface.ROTATION_90))
- .buildRotationTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance().buildRotationTest(instrumentation,
+ supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)) {
+ configuration ->
withTestName { buildTestTag("PipRotationTest", testApp, configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt
index 1502bcdf3a11..3e7eb134e627 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToAppTest.kt
@@ -20,7 +20,6 @@ import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.focusChanges
@@ -54,18 +53,16 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 152738416)
class PipToAppTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = PipAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation, listOf(Surface.ROTATION_0))
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
+ supportedRotations = listOf(Surface.ROTATION_0)) { configuration ->
withTestName { buildTestTag("exitPipModeToApp", testApp, configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToHomeTest.kt
index df88a2da0a92..5d3bc1388686 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipToHomeTest.kt
@@ -20,7 +20,6 @@ import android.view.Surface
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.focusChanges
@@ -53,18 +52,16 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 152738416)
class PipToHomeTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = PipAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation, listOf(Surface.ROTATION_0))
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance().buildTest(instrumentation,
+ supportedRotations = listOf(Surface.ROTATION_0)) { configuration ->
withTestName { buildTestTag("exitPipModeToApp", testApp, configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 7c9b9c37c2c4..d3a736e9153e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -41,6 +41,7 @@ import androidx.test.filters.SmallTest;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.bubbles.BubbleData.TimeSource;
+import com.android.wm.shell.common.ShellExecutor;
import com.google.common.collect.ImmutableList;
@@ -98,6 +99,8 @@ public class BubbleDataTest extends ShellTestCase {
private PendingIntent mDeleteIntent;
@Mock
private BubbleLogger mBubbleLogger;
+ @Mock
+ private ShellExecutor mMainExecutor;
@Captor
private ArgumentCaptor<BubbleData.Update> mUpdateCaptor;
@@ -124,21 +127,31 @@ public class BubbleDataTest extends ShellTestCase {
mock(NotificationListenerService.Ranking.class);
when(ranking.visuallyInterruptive()).thenReturn(true);
mEntryInterruptive = createBubbleEntry(1, "interruptive", "package.d", ranking);
- mBubbleInterruptive = new Bubble(mEntryInterruptive, mSuppressionListener, null);
+ mBubbleInterruptive = new Bubble(mEntryInterruptive, mSuppressionListener, null,
+ mMainExecutor);
mEntryDismissed = createBubbleEntry(1, "dismissed", "package.d", null);
- mBubbleDismissed = new Bubble(mEntryDismissed, mSuppressionListener, null);
-
- mBubbleA1 = new Bubble(mEntryA1, mSuppressionListener, mPendingIntentCanceledListener);
- mBubbleA2 = new Bubble(mEntryA2, mSuppressionListener, mPendingIntentCanceledListener);
- mBubbleA3 = new Bubble(mEntryA3, mSuppressionListener, mPendingIntentCanceledListener);
- mBubbleB1 = new Bubble(mEntryB1, mSuppressionListener, mPendingIntentCanceledListener);
- mBubbleB2 = new Bubble(mEntryB2, mSuppressionListener, mPendingIntentCanceledListener);
- mBubbleB3 = new Bubble(mEntryB3, mSuppressionListener, mPendingIntentCanceledListener);
- mBubbleC1 = new Bubble(mEntryC1, mSuppressionListener, mPendingIntentCanceledListener);
+ mBubbleDismissed = new Bubble(mEntryDismissed, mSuppressionListener, null,
+ mMainExecutor);
+
+ mBubbleA1 = new Bubble(mEntryA1, mSuppressionListener, mPendingIntentCanceledListener,
+ mMainExecutor);
+ mBubbleA2 = new Bubble(mEntryA2, mSuppressionListener, mPendingIntentCanceledListener,
+ mMainExecutor);
+ mBubbleA3 = new Bubble(mEntryA3, mSuppressionListener, mPendingIntentCanceledListener,
+ mMainExecutor);
+ mBubbleB1 = new Bubble(mEntryB1, mSuppressionListener, mPendingIntentCanceledListener,
+ mMainExecutor);
+ mBubbleB2 = new Bubble(mEntryB2, mSuppressionListener, mPendingIntentCanceledListener,
+ mMainExecutor);
+ mBubbleB3 = new Bubble(mEntryB3, mSuppressionListener, mPendingIntentCanceledListener,
+ mMainExecutor);
+ mBubbleC1 = new Bubble(mEntryC1, mSuppressionListener, mPendingIntentCanceledListener,
+ mMainExecutor);
TestableBubblePositioner positioner = new TestableBubblePositioner(mContext,
mock(WindowManager.class));
- mBubbleData = new BubbleData(getContext(), mBubbleLogger, positioner);
+ mBubbleData = new BubbleData(getContext(), mBubbleLogger, positioner,
+ mMainExecutor);
// Used by BubbleData to set lastAccessedTime
when(mTimeSource.currentTimeMillis()).thenReturn(1000L);
@@ -796,7 +809,7 @@ public class BubbleDataTest extends ShellTestCase {
assertWithMessage("addedBubble").that(update.addedBubble).isEqualTo(expected);
}
- private void assertBubbleRemoved(Bubble expected, @BubbleController.DismissReason int reason) {
+ private void assertBubbleRemoved(Bubble expected, @Bubbles.DismissReason int reason) {
BubbleData.Update update = mUpdateCaptor.getValue();
assertWithMessage("removedBubbles").that(update.removedBubbles)
.isEqualTo(ImmutableList.of(Pair.create(expected, reason)));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
index bde04b604c79..fc828b30279f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTest.java
@@ -39,6 +39,7 @@ import androidx.test.filters.SmallTest;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.common.ShellExecutor;
import org.junit.Before;
import org.junit.Test;
@@ -54,6 +55,8 @@ public class BubbleTest extends ShellTestCase {
private Notification mNotif;
@Mock
private StatusBarNotification mSbn;
+ @Mock
+ private ShellExecutor mMainExecutor;
private BubbleEntry mBubbleEntry;
private Bundle mExtras;
@@ -78,7 +81,7 @@ public class BubbleTest extends ShellTestCase {
when(mNotif.getBubbleMetadata()).thenReturn(metadata);
when(mSbn.getKey()).thenReturn("mock");
mBubbleEntry = new BubbleEntry(mSbn, null, true, false, false, false);
- mBubble = new Bubble(mBubbleEntry, mSuppressionListener, null);
+ mBubble = new Bubble(mBubbleEntry, mSuppressionListener, null, mMainExecutor);
}
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java
index 0d4d1269f767..35656bde7169 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java
@@ -47,17 +47,17 @@ public class PipTouchStateTest extends ShellTestCase {
private PipTouchState mTouchState;
private CountDownLatch mDoubleTapCallbackTriggeredLatch;
private CountDownLatch mHoverExitCallbackTriggeredLatch;
- private TestShellExecutor mShellMainExecutor;
+ private TestShellExecutor mMainExecutor;
@Before
public void setUp() throws Exception {
- mShellMainExecutor = new TestShellExecutor();
+ mMainExecutor = new TestShellExecutor();
mDoubleTapCallbackTriggeredLatch = new CountDownLatch(1);
mHoverExitCallbackTriggeredLatch = new CountDownLatch(1);
mTouchState = new PipTouchState(ViewConfiguration.get(getContext()),
mDoubleTapCallbackTriggeredLatch::countDown,
mHoverExitCallbackTriggeredLatch::countDown,
- mShellMainExecutor);
+ mMainExecutor);
assertFalse(mTouchState.isDoubleTap());
assertFalse(mTouchState.isWaitingForDoubleTap());
}
@@ -87,7 +87,7 @@ public class PipTouchStateTest extends ShellTestCase {
assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == 10);
mTouchState.scheduleDoubleTapTimeoutCallback();
- mShellMainExecutor.flushAll();
+ mMainExecutor.flushAll();
assertTrue(mDoubleTapCallbackTriggeredLatch.getCount() == 0);
}
@@ -122,7 +122,7 @@ public class PipTouchStateTest extends ShellTestCase {
@Test
public void testHoverExitTimeout_timeoutCallbackCalled() throws Exception {
mTouchState.scheduleHoverExitTimeoutCallback();
- mShellMainExecutor.flushAll();
+ mMainExecutor.flushAll();
assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 0);
}
@@ -137,7 +137,7 @@ public class PipTouchStateTest extends ShellTestCase {
mTouchState.scheduleHoverExitTimeoutCallback();
mTouchState.onTouchEvent(createMotionEvent(ACTION_BUTTON_PRESS, SystemClock.uptimeMillis(),
0, 0));
- mShellMainExecutor.flushAll();
+ mMainExecutor.flushAll();
assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 1);
}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 615bf4de9fcc..ce1d96c167d7 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -435,6 +435,7 @@ cc_defaults {
"canvas/CanvasFrontend.cpp",
"canvas/CanvasOpBuffer.cpp",
"canvas/CanvasOpRasterizer.cpp",
+ "effects/StretchEffect.cpp",
"pipeline/skia/SkiaDisplayList.cpp",
"pipeline/skia/SkiaRecordingCanvas.cpp",
"pipeline/skia/RenderNodeDrawable.cpp",
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index aeb60e6ce355..609706e2e49d 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -23,6 +23,7 @@
#include "Outline.h"
#include "Rect.h"
#include "RevealClip.h"
+#include "effects/StretchEffect.h"
#include "utils/MathUtils.h"
#include "utils/PaintUtils.h"
@@ -98,6 +99,10 @@ public:
SkImageFilter* getImageFilter() const { return mImageFilter.get(); }
+ const StretchEffect& getStretchEffect() const { return mStretchEffect; }
+
+ StretchEffect& mutableStretchEffect() { return mStretchEffect; }
+
// Sets alpha, xfermode, and colorfilter from an SkPaint
// paint may be NULL, in which case defaults will be set
bool setFromPaint(const SkPaint* paint);
@@ -124,6 +129,7 @@ private:
SkBlendMode mMode;
sk_sp<SkColorFilter> mColorFilter;
sk_sp<SkImageFilter> mImageFilter;
+ StretchEffect mStretchEffect;
};
/*
diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp
new file mode 100644
index 000000000000..51cbc7592861
--- /dev/null
+++ b/libs/hwui/effects/StretchEffect.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "StretchEffect.h"
+
+namespace android::uirenderer {
+
+sk_sp<SkImageFilter> StretchEffect::getImageFilter() const {
+ // TODO: Implement & Cache
+ // Probably need to use mutable to achieve caching
+ return nullptr;
+}
+
+} // namespace android::uirenderer \ No newline at end of file
diff --git a/libs/hwui/effects/StretchEffect.h b/libs/hwui/effects/StretchEffect.h
new file mode 100644
index 000000000000..7dfd6398765a
--- /dev/null
+++ b/libs/hwui/effects/StretchEffect.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "utils/MathUtils.h"
+
+#include <SkPoint.h>
+#include <SkRect.h>
+#include <SkImageFilter.h>
+
+namespace android::uirenderer {
+
+// TODO: Inherit from base RenderEffect type?
+class StretchEffect {
+public:
+ enum class StretchInterpolator {
+ SmoothStep,
+ };
+
+ bool isEmpty() const {
+ return MathUtils::isZero(stretchDirection.x())
+ && MathUtils::isZero(stretchDirection.y());
+ }
+
+ void setEmpty() {
+ *this = StretchEffect{};
+ }
+
+ void mergeWith(const StretchEffect& other) {
+ if (other.isEmpty()) {
+ return;
+ }
+ if (isEmpty()) {
+ *this = other;
+ return;
+ }
+ stretchDirection += other.stretchDirection;
+ if (isEmpty()) {
+ return setEmpty();
+ }
+ stretchArea.join(other.stretchArea);
+ maxStretchAmount = std::max(maxStretchAmount, other.maxStretchAmount);
+ }
+
+ sk_sp<SkImageFilter> getImageFilter() const;
+
+ SkRect stretchArea {0, 0, 0, 0};
+ SkVector stretchDirection {0, 0};
+ float maxStretchAmount = 0;
+};
+
+} // namespace android::uirenderer
diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp
index 8b35d96aeac8..80239687a7fb 100644
--- a/libs/hwui/jni/android_graphics_RenderNode.cpp
+++ b/libs/hwui/jni/android_graphics_RenderNode.cpp
@@ -166,6 +166,31 @@ static jboolean android_view_RenderNode_setOutlineNone(CRITICAL_JNI_PARAMS_COMMA
return true;
}
+static jboolean android_view_RenderNode_clearStretch(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ auto& stretch = renderNode->mutateStagingProperties()
+ .mutateLayerProperties().mutableStretchEffect();
+ if (stretch.isEmpty()) {
+ return false;
+ }
+ stretch.setEmpty();
+ renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+ return true;
+}
+
+static jboolean android_view_RenderNode_stretch(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
+ jfloat left, jfloat top, jfloat right, jfloat bottom, jfloat vX, jfloat vY, jfloat max) {
+ RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
+ renderNode->mutateStagingProperties().mutateLayerProperties().mutableStretchEffect().mergeWith(
+ StretchEffect{
+ .stretchArea = SkRect::MakeLTRB(left, top, right, bottom),
+ .stretchDirection = {.fX = vX, .fY = vY},
+ .maxStretchAmount = max
+ });
+ renderNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+ return true;
+}
+
static jboolean android_view_RenderNode_hasShadow(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
return renderNode->stagingProperties().hasShadow();
@@ -678,6 +703,8 @@ static const JNINativeMethod gMethods[] = {
{ "nSetOutlinePath", "(JJF)Z", (void*) android_view_RenderNode_setOutlinePath },
{ "nSetOutlineEmpty", "(J)Z", (void*) android_view_RenderNode_setOutlineEmpty },
{ "nSetOutlineNone", "(J)Z", (void*) android_view_RenderNode_setOutlineNone },
+ { "nClearStretch", "(J)Z", (void*) android_view_RenderNode_clearStretch },
+ { "nStretch", "(JFFFFFFF)Z", (void*) android_view_RenderNode_stretch },
{ "nHasShadow", "(J)Z", (void*) android_view_RenderNode_hasShadow },
{ "nSetSpotShadowColor", "(JI)Z", (void*) android_view_RenderNode_setSpotShadowColor },
{ "nGetSpotShadowColor", "(J)I", (void*) android_view_RenderNode_getSpotShadowColor },
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 75815bb6e63d..c01021221f37 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -20,6 +20,8 @@
#include "SkiaDisplayList.h"
#include "utils/TraceUtils.h"
+#include <include/effects/SkImageFilters.h>
+
#include <optional>
namespace android {
@@ -171,11 +173,25 @@ static bool layerNeedsPaint(const LayerProperties& properties, float alphaMultip
SkPaint* paint) {
if (alphaMultiplier < 1.0f || properties.alpha() < 255 ||
properties.xferMode() != SkBlendMode::kSrcOver || properties.getColorFilter() != nullptr ||
- properties.getImageFilter() != nullptr) {
+ properties.getImageFilter() != nullptr || !properties.getStretchEffect().isEmpty()) {
paint->setAlpha(properties.alpha() * alphaMultiplier);
paint->setBlendMode(properties.xferMode());
paint->setColorFilter(sk_ref_sp(properties.getColorFilter()));
- paint->setImageFilter(sk_ref_sp(properties.getImageFilter()));
+
+ sk_sp<SkImageFilter> imageFilter = sk_ref_sp(properties.getImageFilter());
+ sk_sp<SkImageFilter> stretchFilter = properties.getStretchEffect().getImageFilter();
+ sk_sp<SkImageFilter> filter;
+ if (imageFilter && stretchFilter) {
+ filter = SkImageFilters::Compose(
+ std::move(stretchFilter),
+ std::move(imageFilter)
+ );
+ } else if (stretchFilter) {
+ filter = std::move(stretchFilter);
+ } else {
+ filter = std::move(imageFilter);
+ }
+ paint->setImageFilter(std::move(filter));
return true;
}
return false;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index eacabfd1dbf9..633f21ceba07 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -490,9 +490,11 @@ void CanvasContext::draw() {
if (mNativeSurface) {
// TODO(b/165985262): measure performance impact
- if (const auto vsyncId = mCurrentFrameInfo->get(FrameInfoIndex::FrameTimelineVsyncId);
- vsyncId != UiFrameInfoBuilder::INVALID_VSYNC_ID) {
- native_window_set_frame_timeline_vsync(mNativeSurface->getNativeWindow(), vsyncId);
+ const auto vsyncId = mCurrentFrameInfo->get(FrameInfoIndex::FrameTimelineVsyncId);
+ if (vsyncId != UiFrameInfoBuilder::INVALID_VSYNC_ID) {
+ const auto inputEventId = mCurrentFrameInfo->get(FrameInfoIndex::NewestInputEvent);
+ native_window_set_frame_timeline_info(mNativeSurface->getNativeWindow(), vsyncId,
+ inputEventId);
}
}
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 3d188c0acce3..65a0110ad87e 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -31,6 +31,7 @@ import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
@@ -1775,6 +1776,7 @@ public final class GnssMeasurement implements Parcelable {
*/
@Nullable
@SystemApi
+ @SuppressLint("NullableCollection")
public Collection<CorrelationVector> getCorrelationVectors() {
return mReadOnlyCorrelationVectors;
}
@@ -1785,7 +1787,9 @@ public final class GnssMeasurement implements Parcelable {
* @hide
*/
@TestApi
- public void setCorrelationVectors(@Nullable Collection<CorrelationVector> correlationVectors) {
+ public void setCorrelationVectors(
+ @SuppressLint("NullableCollection")
+ @Nullable Collection<CorrelationVector> correlationVectors) {
if (correlationVectors == null || correlationVectors.isEmpty()) {
resetCorrelationVectors();
} else {
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 96ec59021d28..fdb044d0dcf6 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -2233,6 +2233,7 @@ public class LocationManager {
* @see #getGnssCapabilities()
*/
@Nullable
+ @SuppressLint("NullableCollection")
public List<GnssAntennaInfo> getGnssAntennaInfos() {
try {
return mService.getGnssAntennaInfos();
diff --git a/location/java/android/location/provider/LocationProviderBase.java b/location/java/android/location/provider/LocationProviderBase.java
index 1306ea2c0204..8f455cd7df07 100644
--- a/location/java/android/location/provider/LocationProviderBase.java
+++ b/location/java/android/location/provider/LocationProviderBase.java
@@ -255,7 +255,9 @@ public abstract class LocationProviderBase {
/**
* Implements optional custom commands.
*/
- public abstract void onSendExtraCommand(@NonNull String command, @Nullable Bundle extras);
+ public abstract void onSendExtraCommand(@NonNull String command,
+ @SuppressLint("NullableCollection")
+ @Nullable Bundle extras);
private final class Service extends ILocationProvider.Stub {
diff --git a/media/java/android/media/MediaServiceManager.java b/media/java/android/media/MediaServiceManager.java
index 96bff4f92668..b899559d2e50 100644
--- a/media/java/android/media/MediaServiceManager.java
+++ b/media/java/android/media/MediaServiceManager.java
@@ -33,6 +33,7 @@ import android.os.ServiceManager;
public class MediaServiceManager {
private static final String MEDIA_SESSION_SERVICE = "media_session";
private static final String MEDIA_TRANSCODING_SERVICE = "media.transcoding";
+ private static final String MEDIA_COMMUNICATION_SERVICE = "media_communication";
/**
* @hide
@@ -79,4 +80,12 @@ public class MediaServiceManager {
public ServiceRegisterer getMediaTranscodingServiceRegisterer() {
return new ServiceRegisterer(MEDIA_TRANSCODING_SERVICE);
}
+
+ /**
+ * Returns {@link ServiceRegisterer} for MEDIA_COMMUNICATION_SERVICE.
+ */
+ @NonNull
+ public ServiceRegisterer getMediaCommunicationServiceRegisterer() {
+ return new ServiceRegisterer(MEDIA_COMMUNICATION_SERVICE);
+ }
}
diff --git a/media/java/android/media/musicrecognition/MusicRecognitionManager.java b/media/java/android/media/musicrecognition/MusicRecognitionManager.java
index 6bbcfd3b5b66..b183eaff83ec 100644
--- a/media/java/android/media/musicrecognition/MusicRecognitionManager.java
+++ b/media/java/android/media/musicrecognition/MusicRecognitionManager.java
@@ -23,6 +23,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
@@ -90,7 +91,9 @@ public class MusicRecognitionManager {
* supplied bundle
*/
void onRecognitionSucceeded(@NonNull RecognitionRequest recognitionRequest,
- @NonNull MediaMetadata result, @Nullable Bundle extras);
+ @NonNull MediaMetadata result,
+ @SuppressLint("NullableCollection")
+ @Nullable Bundle extras);
/**
* Invoked when the search is not successful (possibly but not necessarily due to error).
diff --git a/media/java/android/media/musicrecognition/MusicRecognitionService.java b/media/java/android/media/musicrecognition/MusicRecognitionService.java
index e2071b84c00b..04b4c39bf0fa 100644
--- a/media/java/android/media/musicrecognition/MusicRecognitionService.java
+++ b/media/java/android/media/musicrecognition/MusicRecognitionService.java
@@ -20,6 +20,7 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
@@ -53,7 +54,9 @@ public abstract class MusicRecognitionService extends Service {
* @param extras extra data to be supplied back to the caller. Note that all executable
* parameters and file descriptors would be removed from the supplied bundle
*/
- void onRecognitionSucceeded(@NonNull MediaMetadata result, @Nullable Bundle extras);
+ void onRecognitionSucceeded(@NonNull MediaMetadata result,
+ @SuppressLint("NullableCollection")
+ @Nullable Bundle extras);
/**
* Call this method if the search does not find a result on an error occurred.
diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java
index 4d835b22e34c..8525e9979aef 100644
--- a/media/java/android/media/tv/tuner/Tuner.java
+++ b/media/java/android/media/tv/tuner/Tuner.java
@@ -22,6 +22,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.content.Context;
import android.hardware.tv.tuner.V1_0.Constants;
@@ -1017,6 +1018,7 @@ public class Tuner implements AutoCloseable {
* failed.
*/
@Nullable
+ @SuppressLint("NullableCollection")
public List<FrontendInfo> getAvailableFrontendInfos() {
FrontendInfo[] feInfoList = getFrontendInfoListInternal();
if (feInfoList == null) {
diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java
index 9f327c93f63b..51b685aeb8be 100644
--- a/media/java/android/media/tv/tuner/filter/Filter.java
+++ b/media/java/android/media/tv/tuner/filter/Filter.java
@@ -284,6 +284,12 @@ public class Filter implements AutoCloseable {
/**
* Configures the filter.
*
+ * <p>Recofiguring must happen after stopping the filter.
+ *
+ * <p>When stopping, reconfiguring and restarting the filter, the client should discard all
+ * coming events until it receives {@link RestartEvent} through {@link FilterCallback} to avoid
+ * using the events from the previous configuration.
+ *
* @param config the configuration of the filter.
* @return result status of the operation.
*/
@@ -393,6 +399,10 @@ public class Filter implements AutoCloseable {
*
* <p>Does nothing if the filter is already started.
*
+ * <p>When stopping, reconfiguring and restarting the filter, the client should discard all
+ * coming events until it receives {@link RestartEvent} through {@link FilterCallback} to avoid
+ * using the events from the previous configuration.
+ *
* @return result status of the operation.
*/
@Result
@@ -409,6 +419,12 @@ public class Filter implements AutoCloseable {
*
* <p>Does nothing if the filter is stopped or not started.
*
+ * <p>Filter must be stopped to reconfigure.
+ *
+ * <p>When stopping, reconfiguring and restarting the filter, the client should discard all
+ * coming events until it receives {@link RestartEvent} through {@link FilterCallback} to avoid
+ * using the events from the previous configuration.
+ *
* @return result status of the operation.
*/
@Result
diff --git a/media/java/android/media/tv/tuner/filter/RestartEvent.java b/media/java/android/media/tv/tuner/filter/RestartEvent.java
index 069630188e55..9c5992af5f48 100644
--- a/media/java/android/media/tv/tuner/filter/RestartEvent.java
+++ b/media/java/android/media/tv/tuner/filter/RestartEvent.java
@@ -19,17 +19,29 @@ package android.media.tv.tuner.filter;
import android.annotation.SystemApi;
/**
- * An Event that the client would reveice after stopping, reconfiguring and restarting a filter.
+ * An Event that the client would receive after starting a filter. This event is optional to be
+ * received on the newly opened and started filter. It must be received after stopping,
+ * reconfiguring and restarting a Filter to differentiate the valid reconfigured events from the
+ * previous events.
*
* <p>After stopping and restarting the filter, the client has to discard all coming events until
* it receives {@link RestartEvent} to avoid using the events from the previous configuration.
*
* <p>Recofiguring must happen after stopping the filter.
*
+ * @see Filter#stop()
+ * @see Filter#start()
+ * @see Filter#configure(FilterConfiguration)
+ *
* @hide
*/
@SystemApi
public final class RestartEvent extends FilterEvent {
+ /**
+ * The stard id reserved for the newly opened filter's first start event.
+ */
+ public static final int NEW_FILTER_FIRST_START_ID = 0;
+
private final int mStartId;
// This constructor is used by JNI code only
@@ -38,13 +50,13 @@ public final class RestartEvent extends FilterEvent {
}
/**
- * Gets the start id.
+ * Gets the start id sent via the current Restart Event.
*
- * <p>An unique ID to mark the start point of receiving the valid filter events after
- * reconfiguring. It must be sent at least once in the first event after the filter is
- * restarted.
+ * <p>An unique ID to mark the start point of receiving the valid reconfigured filter events.
+ * The client must receive at least once after the filter is reconfigured and restarted.
*
- * <p>0 is reserved for the newly opened filter's first start. It's optional to be received.
+ * <p>{@link #NEW_FILTER_FIRST_START_ID} is reserved for the newly opened filter's first start.
+ * It's optional to be received.
*/
public int getStartId() {
return mStartId;
diff --git a/media/jni/android_media_MediaMetricsJNI.cpp b/media/jni/android_media_MediaMetricsJNI.cpp
index c064de299b19..08a8d897c96e 100644
--- a/media/jni/android_media_MediaMetricsJNI.cpp
+++ b/media/jni/android_media_MediaMetricsJNI.cpp
@@ -18,7 +18,6 @@
#include <binder/Parcel.h>
#include <jni.h>
-#include <media/IMediaMetricsService.h>
#include <media/MediaMetricsItem.h>
#include <nativehelper/JNIHelp.h>
#include <variant>
@@ -151,12 +150,7 @@ static jint android_media_MediaMetrics_submit_bytebuffer(
return (jint)BAD_VALUE;
}
- sp<IMediaMetricsService> service = mediametrics::BaseItem::getService();
- if (service == nullptr) {
- ALOGW("Cannot retrieve mediametrics service");
- return (jint)NO_INIT;
- }
- return (jint)service->submitBuffer((char *)buffer, length);
+ return (jint)mediametrics::BaseItem::submitBuffer((char *)buffer, length);
}
// Helper function to convert a native PersistableBundle to a Java
diff --git a/core/java/android/net/CaptivePortal.java b/packages/Connectivity/framework/src/android/net/CaptivePortal.java
index 269bbf20c8b1..269bbf20c8b1 100644
--- a/core/java/android/net/CaptivePortal.java
+++ b/packages/Connectivity/framework/src/android/net/CaptivePortal.java
diff --git a/core/java/android/net/CaptivePortalData.aidl b/packages/Connectivity/framework/src/android/net/CaptivePortalData.aidl
index 1d57ee759136..1d57ee759136 100644
--- a/core/java/android/net/CaptivePortalData.aidl
+++ b/packages/Connectivity/framework/src/android/net/CaptivePortalData.aidl
diff --git a/core/java/android/net/CaptivePortalData.java b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
index 9b56b23cc879..9b56b23cc879 100644
--- a/core/java/android/net/CaptivePortalData.java
+++ b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
diff --git a/core/java/android/net/ConnectionInfo.aidl b/packages/Connectivity/framework/src/android/net/ConnectionInfo.aidl
index 07faf8bbbed8..07faf8bbbed8 100644
--- a/core/java/android/net/ConnectionInfo.aidl
+++ b/packages/Connectivity/framework/src/android/net/ConnectionInfo.aidl
diff --git a/core/java/android/net/ConnectionInfo.java b/packages/Connectivity/framework/src/android/net/ConnectionInfo.java
index 4514a8484d96..4514a8484d96 100644
--- a/core/java/android/net/ConnectionInfo.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectionInfo.java
diff --git a/core/java/android/net/ConnectivityDiagnosticsManager.aidl b/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.aidl
index 82ba0ca113c5..82ba0ca113c5 100644
--- a/core/java/android/net/ConnectivityDiagnosticsManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.aidl
diff --git a/core/java/android/net/ConnectivityDiagnosticsManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.java
index 523449497345..523449497345 100644
--- a/core/java/android/net/ConnectivityDiagnosticsManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.java
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
new file mode 100644
index 000000000000..9afa5d1311c5
--- /dev/null
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityFrameworkInitializer.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 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.net;
+
+import android.annotation.SystemApi;
+import android.app.SystemServiceRegistry;
+import android.content.Context;
+
+/**
+ * Class for performing registration for all core connectivity services.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class ConnectivityFrameworkInitializer {
+ private ConnectivityFrameworkInitializer() {}
+
+ /**
+ * Called by {@link SystemServiceRegistry}'s static initializer and registers all core
+ * connectivity services to {@link Context}, so that {@link Context#getSystemService} can
+ * return them.
+ *
+ * @throws IllegalStateException if this is called anywhere besides
+ * {@link SystemServiceRegistry}.
+ */
+ public static void registerServiceWrappers() {
+ // registerContextAwareService will throw if this is called outside of SystemServiceRegistry
+ // initialization.
+ SystemServiceRegistry.registerContextAwareService(
+ Context.CONNECTIVITY_SERVICE,
+ ConnectivityManager.class,
+ (context, serviceBinder) -> {
+ IConnectivityManager icm = IConnectivityManager.Stub.asInterface(serviceBinder);
+ return new ConnectivityManager(context, icm);
+ }
+ );
+
+ // TODO: move outside of the connectivity JAR
+ SystemServiceRegistry.registerContextAwareService(
+ Context.VPN_MANAGEMENT_SERVICE,
+ VpnManager.class,
+ (context) -> {
+ final ConnectivityManager cm = context.getSystemService(
+ ConnectivityManager.class);
+ return cm.createVpnManager();
+ }
+ );
+
+ SystemServiceRegistry.registerContextAwareService(
+ Context.CONNECTIVITY_DIAGNOSTICS_SERVICE,
+ ConnectivityDiagnosticsManager.class,
+ (context) -> {
+ final ConnectivityManager cm = context.getSystemService(
+ ConnectivityManager.class);
+ return cm.createDiagnosticsManager();
+ }
+ );
+
+ SystemServiceRegistry.registerContextAwareService(
+ Context.TEST_NETWORK_SERVICE,
+ TestNetworkManager.class,
+ context -> {
+ final ConnectivityManager cm = context.getSystemService(
+ ConnectivityManager.class);
+ return cm.startOrGetTestNetworkManager();
+ }
+ );
+ }
+}
diff --git a/core/java/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index ac8f9c9e62fd..2a0a74ed0604 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -4823,6 +4823,28 @@ public class ConnectivityManager {
}
}
+ /** @hide */
+ public TestNetworkManager startOrGetTestNetworkManager() {
+ final IBinder tnBinder;
+ try {
+ tnBinder = mService.startOrGetTestNetworkService();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ return new TestNetworkManager(ITestNetworkManager.Stub.asInterface(tnBinder));
+ }
+
+ /** @hide */
+ public VpnManager createVpnManager() {
+ return new VpnManager(mContext, mService);
+ }
+
+ /** @hide */
+ public ConnectivityDiagnosticsManager createDiagnosticsManager() {
+ return new ConnectivityDiagnosticsManager(mContext, mService);
+ }
+
/**
* Simulates a Data Stall for the specified Network.
*
diff --git a/core/java/android/net/ConnectivityMetricsEvent.aidl b/packages/Connectivity/framework/src/android/net/ConnectivityMetricsEvent.aidl
index 1c541dc4c8cc..1c541dc4c8cc 100644
--- a/core/java/android/net/ConnectivityMetricsEvent.aidl
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityMetricsEvent.aidl
diff --git a/core/java/android/net/ConnectivityThread.java b/packages/Connectivity/framework/src/android/net/ConnectivityThread.java
index 0b218e738b77..0b218e738b77 100644
--- a/core/java/android/net/ConnectivityThread.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityThread.java
diff --git a/core/java/android/net/DhcpInfo.aidl b/packages/Connectivity/framework/src/android/net/DhcpInfo.aidl
index 29cd21fe7652..29cd21fe7652 100644
--- a/core/java/android/net/DhcpInfo.aidl
+++ b/packages/Connectivity/framework/src/android/net/DhcpInfo.aidl
diff --git a/core/java/android/net/DhcpInfo.java b/packages/Connectivity/framework/src/android/net/DhcpInfo.java
index 912df67a0b45..912df67a0b45 100644
--- a/core/java/android/net/DhcpInfo.java
+++ b/packages/Connectivity/framework/src/android/net/DhcpInfo.java
diff --git a/core/java/android/net/DnsResolver.java b/packages/Connectivity/framework/src/android/net/DnsResolver.java
index 3f7660f5709a..3f7660f5709a 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/packages/Connectivity/framework/src/android/net/DnsResolver.java
diff --git a/core/java/android/net/ICaptivePortal.aidl b/packages/Connectivity/framework/src/android/net/ICaptivePortal.aidl
index fe21905c7002..fe21905c7002 100644
--- a/core/java/android/net/ICaptivePortal.aidl
+++ b/packages/Connectivity/framework/src/android/net/ICaptivePortal.aidl
diff --git a/core/java/android/net/IConnectivityDiagnosticsCallback.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityDiagnosticsCallback.aidl
index 82b64a928000..82b64a928000 100644
--- a/core/java/android/net/IConnectivityDiagnosticsCallback.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityDiagnosticsCallback.aidl
diff --git a/core/java/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
index 1b4d2e413943..1b4d2e413943 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
diff --git a/core/java/android/net/ISocketKeepaliveCallback.aidl b/packages/Connectivity/framework/src/android/net/ISocketKeepaliveCallback.aidl
index 020fbcacbfef..020fbcacbfef 100644
--- a/core/java/android/net/ISocketKeepaliveCallback.aidl
+++ b/packages/Connectivity/framework/src/android/net/ISocketKeepaliveCallback.aidl
diff --git a/core/java/android/net/ITestNetworkManager.aidl b/packages/Connectivity/framework/src/android/net/ITestNetworkManager.aidl
index 2a863adde581..2a863adde581 100644
--- a/core/java/android/net/ITestNetworkManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/ITestNetworkManager.aidl
diff --git a/core/java/android/net/InetAddresses.java b/packages/Connectivity/framework/src/android/net/InetAddresses.java
index 01b795e456fa..01b795e456fa 100644
--- a/core/java/android/net/InetAddresses.java
+++ b/packages/Connectivity/framework/src/android/net/InetAddresses.java
diff --git a/core/java/android/net/InterfaceConfiguration.aidl b/packages/Connectivity/framework/src/android/net/InterfaceConfiguration.aidl
index 8aa5e3452853..8aa5e3452853 100644
--- a/core/java/android/net/InterfaceConfiguration.aidl
+++ b/packages/Connectivity/framework/src/android/net/InterfaceConfiguration.aidl
diff --git a/core/java/android/net/InvalidPacketException.java b/packages/Connectivity/framework/src/android/net/InvalidPacketException.java
index 1873d778c0f2..1873d778c0f2 100644
--- a/core/java/android/net/InvalidPacketException.java
+++ b/packages/Connectivity/framework/src/android/net/InvalidPacketException.java
diff --git a/core/java/android/net/IpConfiguration.aidl b/packages/Connectivity/framework/src/android/net/IpConfiguration.aidl
index 7a30f0e79cad..7a30f0e79cad 100644
--- a/core/java/android/net/IpConfiguration.aidl
+++ b/packages/Connectivity/framework/src/android/net/IpConfiguration.aidl
diff --git a/core/java/android/net/IpConfiguration.java b/packages/Connectivity/framework/src/android/net/IpConfiguration.java
index d5f8b2edb6bb..d5f8b2edb6bb 100644
--- a/core/java/android/net/IpConfiguration.java
+++ b/packages/Connectivity/framework/src/android/net/IpConfiguration.java
diff --git a/core/java/android/net/IpPrefix.aidl b/packages/Connectivity/framework/src/android/net/IpPrefix.aidl
index 0d70f2a1ed2c..0d70f2a1ed2c 100644
--- a/core/java/android/net/IpPrefix.aidl
+++ b/packages/Connectivity/framework/src/android/net/IpPrefix.aidl
diff --git a/core/java/android/net/IpPrefix.java b/packages/Connectivity/framework/src/android/net/IpPrefix.java
index bcb65fab8571..bcb65fab8571 100644
--- a/core/java/android/net/IpPrefix.java
+++ b/packages/Connectivity/framework/src/android/net/IpPrefix.java
diff --git a/core/java/android/net/KeepalivePacketData.aidl b/packages/Connectivity/framework/src/android/net/KeepalivePacketData.aidl
index d456b53fd188..d456b53fd188 100644
--- a/core/java/android/net/KeepalivePacketData.aidl
+++ b/packages/Connectivity/framework/src/android/net/KeepalivePacketData.aidl
diff --git a/core/java/android/net/KeepalivePacketData.java b/packages/Connectivity/framework/src/android/net/KeepalivePacketData.java
index 5877f1f4e269..5877f1f4e269 100644
--- a/core/java/android/net/KeepalivePacketData.java
+++ b/packages/Connectivity/framework/src/android/net/KeepalivePacketData.java
diff --git a/core/java/android/net/LinkAddress.aidl b/packages/Connectivity/framework/src/android/net/LinkAddress.aidl
index 9c804db08d61..9c804db08d61 100644
--- a/core/java/android/net/LinkAddress.aidl
+++ b/packages/Connectivity/framework/src/android/net/LinkAddress.aidl
diff --git a/core/java/android/net/LinkAddress.java b/packages/Connectivity/framework/src/android/net/LinkAddress.java
index d1bdaa078cdc..d1bdaa078cdc 100644
--- a/core/java/android/net/LinkAddress.java
+++ b/packages/Connectivity/framework/src/android/net/LinkAddress.java
diff --git a/core/java/android/net/LinkProperties.aidl b/packages/Connectivity/framework/src/android/net/LinkProperties.aidl
index a8b3c7b0392f..a8b3c7b0392f 100644
--- a/core/java/android/net/LinkProperties.aidl
+++ b/packages/Connectivity/framework/src/android/net/LinkProperties.aidl
diff --git a/core/java/android/net/LinkProperties.java b/packages/Connectivity/framework/src/android/net/LinkProperties.java
index e41ed72b259c..e41ed72b259c 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/packages/Connectivity/framework/src/android/net/LinkProperties.java
diff --git a/core/java/android/net/MacAddress.aidl b/packages/Connectivity/framework/src/android/net/MacAddress.aidl
index 48a18a7ac821..48a18a7ac821 100644
--- a/core/java/android/net/MacAddress.aidl
+++ b/packages/Connectivity/framework/src/android/net/MacAddress.aidl
diff --git a/core/java/android/net/MacAddress.java b/packages/Connectivity/framework/src/android/net/MacAddress.java
index c83c23a4b66e..c83c23a4b66e 100644
--- a/core/java/android/net/MacAddress.java
+++ b/packages/Connectivity/framework/src/android/net/MacAddress.java
diff --git a/core/java/android/net/NattKeepalivePacketData.java b/packages/Connectivity/framework/src/android/net/NattKeepalivePacketData.java
index c4f8fc281f25..c4f8fc281f25 100644
--- a/core/java/android/net/NattKeepalivePacketData.java
+++ b/packages/Connectivity/framework/src/android/net/NattKeepalivePacketData.java
diff --git a/core/java/android/net/NattSocketKeepalive.java b/packages/Connectivity/framework/src/android/net/NattSocketKeepalive.java
index a15d165e65e7..a15d165e65e7 100644
--- a/core/java/android/net/NattSocketKeepalive.java
+++ b/packages/Connectivity/framework/src/android/net/NattSocketKeepalive.java
diff --git a/core/java/android/net/Network.aidl b/packages/Connectivity/framework/src/android/net/Network.aidl
index 05622025bf33..05622025bf33 100644
--- a/core/java/android/net/Network.aidl
+++ b/packages/Connectivity/framework/src/android/net/Network.aidl
diff --git a/core/java/android/net/Network.java b/packages/Connectivity/framework/src/android/net/Network.java
index 46141e0d0c1e..46141e0d0c1e 100644
--- a/core/java/android/net/Network.java
+++ b/packages/Connectivity/framework/src/android/net/Network.java
diff --git a/core/java/android/net/NetworkAgent.java b/packages/Connectivity/framework/src/android/net/NetworkAgent.java
index d22d82d1f4d0..d22d82d1f4d0 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkAgent.java
diff --git a/core/java/android/net/NetworkAgentConfig.aidl b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.aidl
index cb70bdd31260..cb70bdd31260 100644
--- a/core/java/android/net/NetworkAgentConfig.aidl
+++ b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.aidl
diff --git a/core/java/android/net/NetworkAgentConfig.java b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
index 664c2650ff0c..664c2650ff0c 100644
--- a/core/java/android/net/NetworkAgentConfig.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.java
diff --git a/core/java/android/net/NetworkCapabilities.aidl b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.aidl
index 01d328605de4..01d328605de4 100644
--- a/core/java/android/net/NetworkCapabilities.aidl
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.aidl
diff --git a/core/java/android/net/NetworkCapabilities.java b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
index 3843b9ab93c2..0832152d6ab6 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkCapabilities.java
@@ -34,9 +34,9 @@ import android.util.ArraySet;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.BitUtils;
import com.android.internal.util.Preconditions;
+import com.android.net.module.util.CollectionUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -767,7 +767,7 @@ public final class NetworkCapabilities implements Parcelable {
if (originalOwnerUid == creatorUid) {
setOwnerUid(creatorUid);
}
- if (ArrayUtils.contains(originalAdministratorUids, creatorUid)) {
+ if (CollectionUtils.contains(originalAdministratorUids, creatorUid)) {
setAdministratorUids(new int[] {creatorUid});
}
// There is no need to clear the UIDs, they have already been cleared by clearAll() above.
@@ -1873,7 +1873,7 @@ public final class NetworkCapabilities implements Parcelable {
sb.append(" OwnerUid: ").append(mOwnerUid);
}
- if (!ArrayUtils.isEmpty(mAdministratorUids)) {
+ if (mAdministratorUids != null && mAdministratorUids.length != 0) {
sb.append(" AdminUids: ").append(Arrays.toString(mAdministratorUids));
}
@@ -2506,7 +2506,7 @@ public final class NetworkCapabilities implements Parcelable {
@NonNull
public NetworkCapabilities build() {
if (mCaps.getOwnerUid() != Process.INVALID_UID) {
- if (!ArrayUtils.contains(mCaps.getAdministratorUids(), mCaps.getOwnerUid())) {
+ if (!CollectionUtils.contains(mCaps.getAdministratorUids(), mCaps.getOwnerUid())) {
throw new IllegalStateException("The owner UID must be included in "
+ " administrator UIDs.");
}
diff --git a/core/java/android/net/NetworkConfig.java b/packages/Connectivity/framework/src/android/net/NetworkConfig.java
index 32a2cda00370..32a2cda00370 100644
--- a/core/java/android/net/NetworkConfig.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkConfig.java
diff --git a/core/java/android/net/NetworkInfo.aidl b/packages/Connectivity/framework/src/android/net/NetworkInfo.aidl
index f50187302966..f50187302966 100644
--- a/core/java/android/net/NetworkInfo.aidl
+++ b/packages/Connectivity/framework/src/android/net/NetworkInfo.aidl
diff --git a/core/java/android/net/NetworkInfo.java b/packages/Connectivity/framework/src/android/net/NetworkInfo.java
index d752901e2eb0..d752901e2eb0 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkInfo.java
diff --git a/core/java/android/net/NetworkProvider.java b/packages/Connectivity/framework/src/android/net/NetworkProvider.java
index 14cb51c85d06..14cb51c85d06 100644
--- a/core/java/android/net/NetworkProvider.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkProvider.java
diff --git a/core/java/android/net/NetworkRequest.aidl b/packages/Connectivity/framework/src/android/net/NetworkRequest.aidl
index 508defc6b497..508defc6b497 100644
--- a/core/java/android/net/NetworkRequest.aidl
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.aidl
diff --git a/core/java/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index c4d1b09a5c20..c4d1b09a5c20 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
diff --git a/core/java/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
index 8be4af7b1396..8be4af7b1396 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
diff --git a/core/java/android/net/PacProxySelector.java b/packages/Connectivity/framework/src/android/net/PacProxySelector.java
index 326943a27d4e..326943a27d4e 100644
--- a/core/java/android/net/PacProxySelector.java
+++ b/packages/Connectivity/framework/src/android/net/PacProxySelector.java
diff --git a/core/java/android/net/Proxy.java b/packages/Connectivity/framework/src/android/net/Proxy.java
index 03b07e080add..03b07e080add 100644
--- a/core/java/android/net/Proxy.java
+++ b/packages/Connectivity/framework/src/android/net/Proxy.java
diff --git a/core/java/android/net/ProxyInfo.aidl b/packages/Connectivity/framework/src/android/net/ProxyInfo.aidl
index a5d0c120e747..a5d0c120e747 100644
--- a/core/java/android/net/ProxyInfo.aidl
+++ b/packages/Connectivity/framework/src/android/net/ProxyInfo.aidl
diff --git a/core/java/android/net/ProxyInfo.java b/packages/Connectivity/framework/src/android/net/ProxyInfo.java
index 9c9fed102828..9c9fed102828 100644
--- a/core/java/android/net/ProxyInfo.java
+++ b/packages/Connectivity/framework/src/android/net/ProxyInfo.java
diff --git a/core/java/android/net/RouteInfo.aidl b/packages/Connectivity/framework/src/android/net/RouteInfo.aidl
index 7af9fdaef342..7af9fdaef342 100644
--- a/core/java/android/net/RouteInfo.aidl
+++ b/packages/Connectivity/framework/src/android/net/RouteInfo.aidl
diff --git a/core/java/android/net/RouteInfo.java b/packages/Connectivity/framework/src/android/net/RouteInfo.java
index 5b6684ace052..5b6684ace052 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/packages/Connectivity/framework/src/android/net/RouteInfo.java
diff --git a/core/java/android/net/SocketKeepalive.java b/packages/Connectivity/framework/src/android/net/SocketKeepalive.java
index d007a9520cb5..d007a9520cb5 100644
--- a/core/java/android/net/SocketKeepalive.java
+++ b/packages/Connectivity/framework/src/android/net/SocketKeepalive.java
diff --git a/core/java/android/net/StaticIpConfiguration.aidl b/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.aidl
index 8aac701fe7e1..8aac701fe7e1 100644
--- a/core/java/android/net/StaticIpConfiguration.aidl
+++ b/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.aidl
diff --git a/core/java/android/net/StaticIpConfiguration.java b/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.java
index ce545974f5cb..ce545974f5cb 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.java
diff --git a/core/java/android/net/TcpKeepalivePacketData.java b/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java
index ddb3a6a72fb4..ddb3a6a72fb4 100644
--- a/core/java/android/net/TcpKeepalivePacketData.java
+++ b/packages/Connectivity/framework/src/android/net/TcpKeepalivePacketData.java
diff --git a/core/java/android/net/TcpRepairWindow.java b/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java
index f062fa9034ea..f062fa9034ea 100644
--- a/core/java/android/net/TcpRepairWindow.java
+++ b/packages/Connectivity/framework/src/android/net/TcpRepairWindow.java
diff --git a/core/java/android/net/TcpSocketKeepalive.java b/packages/Connectivity/framework/src/android/net/TcpSocketKeepalive.java
index d89814d49bd0..d89814d49bd0 100644
--- a/core/java/android/net/TcpSocketKeepalive.java
+++ b/packages/Connectivity/framework/src/android/net/TcpSocketKeepalive.java
diff --git a/core/java/android/net/TestNetworkInterface.aidl b/packages/Connectivity/framework/src/android/net/TestNetworkInterface.aidl
index e1f4f9f794eb..e1f4f9f794eb 100644
--- a/core/java/android/net/TestNetworkInterface.aidl
+++ b/packages/Connectivity/framework/src/android/net/TestNetworkInterface.aidl
diff --git a/core/java/android/net/TestNetworkInterface.java b/packages/Connectivity/framework/src/android/net/TestNetworkInterface.java
index 4449ff80180b..4449ff80180b 100644
--- a/core/java/android/net/TestNetworkInterface.java
+++ b/packages/Connectivity/framework/src/android/net/TestNetworkInterface.java
diff --git a/core/java/android/net/TestNetworkManager.java b/packages/Connectivity/framework/src/android/net/TestNetworkManager.java
index 4e894143bf91..4e894143bf91 100644
--- a/core/java/android/net/TestNetworkManager.java
+++ b/packages/Connectivity/framework/src/android/net/TestNetworkManager.java
diff --git a/core/java/android/net/TransportInfo.java b/packages/Connectivity/framework/src/android/net/TransportInfo.java
index aa4bbb051179..aa4bbb051179 100644
--- a/core/java/android/net/TransportInfo.java
+++ b/packages/Connectivity/framework/src/android/net/TransportInfo.java
diff --git a/core/java/android/net/UidRange.aidl b/packages/Connectivity/framework/src/android/net/UidRange.aidl
index f70fc8e2fefd..f70fc8e2fefd 100644
--- a/core/java/android/net/UidRange.aidl
+++ b/packages/Connectivity/framework/src/android/net/UidRange.aidl
diff --git a/core/java/android/net/VpnManager.java b/packages/Connectivity/framework/src/android/net/VpnManager.java
index c87b8279c4d6..c87b8279c4d6 100644
--- a/core/java/android/net/VpnManager.java
+++ b/packages/Connectivity/framework/src/android/net/VpnManager.java
diff --git a/core/java/android/net/VpnService.java b/packages/Connectivity/framework/src/android/net/VpnService.java
index 8e90a119fe21..8e90a119fe21 100644
--- a/core/java/android/net/VpnService.java
+++ b/packages/Connectivity/framework/src/android/net/VpnService.java
diff --git a/core/java/android/net/apf/ApfCapabilities.aidl b/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.aidl
index 7c4d4c2da4bc..7c4d4c2da4bc 100644
--- a/core/java/android/net/apf/ApfCapabilities.aidl
+++ b/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.aidl
diff --git a/core/java/android/net/apf/ApfCapabilities.java b/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.java
index bf5b26e278f9..bf5b26e278f9 100644
--- a/core/java/android/net/apf/ApfCapabilities.java
+++ b/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.java
diff --git a/core/java/android/net/util/DnsUtils.java b/packages/Connectivity/framework/src/android/net/util/DnsUtils.java
index 7908353eeda2..7908353eeda2 100644
--- a/core/java/android/net/util/DnsUtils.java
+++ b/packages/Connectivity/framework/src/android/net/util/DnsUtils.java
diff --git a/core/java/android/net/util/KeepaliveUtils.java b/packages/Connectivity/framework/src/android/net/util/KeepaliveUtils.java
index bfc4563fbf8f..bfc4563fbf8f 100644
--- a/core/java/android/net/util/KeepaliveUtils.java
+++ b/packages/Connectivity/framework/src/android/net/util/KeepaliveUtils.java
diff --git a/core/java/android/net/util/MultinetworkPolicyTracker.java b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
index 85e3fa3048ed..85e3fa3048ed 100644
--- a/core/java/android/net/util/MultinetworkPolicyTracker.java
+++ b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
diff --git a/core/java/android/net/util/SocketUtils.java b/packages/Connectivity/framework/src/android/net/util/SocketUtils.java
index e64060f1b220..e64060f1b220 100644
--- a/core/java/android/net/util/SocketUtils.java
+++ b/packages/Connectivity/framework/src/android/net/util/SocketUtils.java
diff --git a/packages/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp
index c8f3bd3666e4..8fc318180778 100644
--- a/packages/Connectivity/service/Android.bp
+++ b/packages/Connectivity/service/Android.bp
@@ -57,6 +57,7 @@ java_library {
static_libs: [
"net-utils-device-common",
"net-utils-framework-common",
+ "netd-client",
],
apex_available: [
"//apex_available:platform",
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml
index 8a73fb52de75..2be00b95af3c 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_off.xml
@@ -15,11 +15,17 @@
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="oval" >
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:top="4dp"
+ android:left="4dp"
+ android:right="4dp"
+ android:bottom="4dp">
- <size android:height="24dp" android:width="24dp" />
- <solid android:color="@color/thumb_off" />
- <stroke android:width="4dp" android:color="@android:color/transparent" />
+ <shape android:shape="oval" >
+ <size android:height="20dp" android:width="20dp" />
+ <solid android:color="@color/thumb_off" />
+ </shape>
-</shape>
+ </item>
+</layer-list>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml
index 8a0af00b0d61..e85eb42007b8 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/thumb_on.xml
@@ -15,11 +15,17 @@
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="oval" >
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:top="4dp"
+ android:left="4dp"
+ android:right="4dp"
+ android:bottom="4dp">
- <size android:height="24dp" android:width="24dp" />
- <solid android:color="?android:attr/colorAccent" />
- <stroke android:width="4dp" android:color="@android:color/transparent" />
+ <shape android:shape="oval" >
+ <size android:height="20dp" android:width="20dp" />
+ <solid android:color="?android:attr/colorAccent" />
+ </shape>
-</shape>
+ </item>
+</layer-list>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off.xml
index 1be3a8eda19e..b29f4596d77c 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off.xml
@@ -20,7 +20,7 @@
<item
android:width="13.33dp"
android:height="1.67dp"
- android:left="19dp"
+ android:left="21dp"
android:gravity="center"
android:drawable="@drawable/track_off_indicator" />
</layer-list>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml
index 3cc490f9815c..c838654dd209 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_off_background.xml
@@ -17,17 +17,17 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="24dp"
- android:viewportWidth="48"
- android:viewportHeight="24">
+ android:width="52dp"
+ android:height="28dp"
+ android:viewportWidth="52"
+ android:viewportHeight="28">
<group>
<clip-path
- android:pathData="M12 0H36C42.6274 0 48 5.37258 48 12C48 18.6274 42.6274 24 36 24H12C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0Z" />
+ android:pathData="M14 0H38C45.732 0 52 6.26801 52 14C52 21.732 45.732 28 38 28H14C6.26801 28 0 21.732 0 14C0 6.26801 6.26801 0 14 0Z" />
<path
- android:pathData="M0 0V24H48V0"
+ android:pathData="M0 0V28H52V0"
android:fillColor="@color/track_off" />
</group>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on.xml
index 255389143782..cf241129f16d 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on.xml
@@ -21,6 +21,6 @@
android:width="13.19dp"
android:height="10.06dp"
android:gravity="center"
- android:right="19dp"
+ android:right="21dp"
android:drawable="@drawable/track_on_indicator" />
</layer-list>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml
index 68ce19b6c67f..bb1a7ef9c733 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/drawable/track_on_background.xml
@@ -17,19 +17,20 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="24dp"
- android:viewportWidth="48"
- android:viewportHeight="24"
+ android:width="52dp"
+ android:height="28dp"
+ android:viewportWidth="52"
+ android:viewportHeight="28"
android:tint="@*android:color/switch_track_material">
<group>
<clip-path
- android:pathData="M12 0H36C42.6274 0 48 5.37258 48 12C48 18.6274 42.6274 24 36 24H12C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0Z" />
+ android:pathData="M14 0H38C45.732 0 52 6.26801 52 14C52 21.732 45.732 28 38 28H14C6.26801 28 0 21.732 0 14C0 6.26801 6.26801 0 14 0Z" />
<path
- android:pathData="M0 0V24H48V0"
+ android:pathData="M0 0V28H52V0"
android:fillColor="@*android:color/white_disabled_material" />
+
</group>
</vector>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml b/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml
index 7e3ce9d3595c..52779bcabf00 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/layout/main_switch_bar.xml
@@ -26,7 +26,7 @@
android:minHeight="@dimen/min_switch_bar_height"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:background="?android:attr/colorBackground"
+ android:background="?android:attr/selectableItemBackground"
android:paddingLeft="@dimen/switchbar_margin_start"
android:paddingRight="@dimen/switchbar_margin_end">
@@ -35,7 +35,7 @@
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
- android:paddingRight="54dp"
+ android:layout_marginRight="16dp"
android:layout_gravity="center_vertical"
android:maxLines="2"
android:ellipsize="end"
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml b/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
index 9dc0af3b5643..147db773fd05 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values-night/colors.xml
@@ -17,7 +17,6 @@
<resources>
- <color name="title_text_color">@*android:color/primary_text_dark</color>
<color name="thumb_off">#BFFFFFFF</color>
<color name="track_off">@*android:color/material_grey_600</color>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml b/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
index 8194bddc99b4..147db773fd05 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/colors.xml
@@ -17,7 +17,6 @@
<resources>
- <color name="title_text_color">@*android:color/primary_text_light</color>
<color name="thumb_off">#BFFFFFFF</color>
<color name="track_off">@*android:color/material_grey_600</color>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
index dd443deeb869..b145c9bc4b39 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/dimens.xml
@@ -18,13 +18,13 @@
<resources>
<!-- Size of layout margin left -->
- <dimen name="switchbar_margin_start">26dp</dimen>
+ <dimen name="switchbar_margin_start">22dp</dimen>
<!-- Size of layout margin right -->
- <dimen name="switchbar_margin_end">24dp</dimen>
+ <dimen name="switchbar_margin_end">16dp</dimen>
<!-- Minimum width of switch -->
- <dimen name="min_switch_width">48dp</dimen>
+ <dimen name="min_switch_width">52dp</dimen>
<!-- Minimum width of switch bar -->
<dimen name="min_switch_bar_height">72dp</dimen>
diff --git a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
index fbb896c76295..59b5899a4173 100644
--- a/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
+++ b/packages/SettingsLib/MainSwitchPreference/res/values/styles.xml
@@ -19,7 +19,6 @@
<style name="MainSwitchText">
<item name="android:textSize">20sp</item>
- <item name="android:textColor">@color/title_text_color</item>
</style>
<style name="Settings.MainSwitch" parent="@android:style/Widget.Material.CompoundButton.Switch">
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
index 532c996824d4..74b65780ffc2 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -136,10 +136,8 @@ public class MainSwitchBar extends LinearLayout implements CompoundButton.OnChec
* Show the MainSwitchBar
*/
public void show() {
- if (!isShowing()) {
- setVisibility(View.VISIBLE);
- mSwitch.setOnCheckedChangeListener(this);
- }
+ setVisibility(View.VISIBLE);
+ mSwitch.setOnCheckedChangeListener(this);
}
/**
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
index dae0e705794d..274bf8df2222 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchPreference.java
@@ -17,9 +17,11 @@
package com.android.settingslib.widget;
import android.content.Context;
+import android.content.res.TypedArray;
+import android.text.TextUtils;
import android.util.AttributeSet;
-import android.widget.Switch;
+import androidx.core.content.res.TypedArrayUtils;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.TwoStatePreference;
@@ -38,30 +40,29 @@ public class MainSwitchPreference extends TwoStatePreference {
private final List<OnMainSwitchChangeListener> mSwitchChangeListeners = new ArrayList<>();
private MainSwitchBar mMainSwitchBar;
- private Switch mSwitch;
private String mTitle;
private RestrictedLockUtils.EnforcedAdmin mEnforcedAdmin;
public MainSwitchPreference(Context context) {
super(context);
- init();
+ init(context, null);
}
public MainSwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
- init();
+ init(context, attrs);
}
public MainSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- init();
+ init(context, attrs);
}
public MainSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- init();
+ init(context, attrs);
}
@Override
@@ -76,8 +77,21 @@ public class MainSwitchPreference extends TwoStatePreference {
registerListenerToSwitchBar();
}
- private void init() {
+ private void init(Context context, AttributeSet attrs) {
setLayoutResource(R.layout.main_switch_layout);
+
+ if (attrs != null) {
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ androidx.preference.R.styleable.Preference, 0 /*defStyleAttr*/,
+ 0 /*defStyleRes*/);
+ final CharSequence title = TypedArrayUtils.getText(a,
+ androidx.preference.R.styleable.Preference_title,
+ androidx.preference.R.styleable.Preference_android_title);
+ if (!TextUtils.isEmpty(title)) {
+ setTitle(title.toString());
+ }
+ a.recycle();
+ }
}
/**
diff --git a/packages/SettingsLib/UsageProgressBarPreference/Android.bp b/packages/SettingsLib/UsageProgressBarPreference/Android.bp
index f346a5962d1c..3331550d0535 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/Android.bp
+++ b/packages/SettingsLib/UsageProgressBarPreference/Android.bp
@@ -6,6 +6,7 @@ android_library {
static_libs: [
"androidx.preference_preference",
+ "androidx-constraintlayout_constraintlayout",
],
sdk_version: "system_current",
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 9dbd5fa4b2d2..f45105dc3311 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
+++ b/packages/SettingsLib/UsageProgressBarPreference/res/layout/preference_usage_progress_bar.xml
@@ -17,6 +17,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
@@ -26,29 +27,40 @@
android:paddingTop="32dp"
android:paddingBottom="32dp">
- <RelativeLayout
+ <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/usage_summary"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_alignParentStart="true"
- android:layout_alignBaseline="@id/total_summary"
- android:singleLine="true"
+ app:layout_constraintWidth_percent="0.45"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintBaseline_toBaselineOf="@id/total_summary"
android:ellipsize="marquee"
android:fontFamily="@*android:string/config_headlineFontFamily"
android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Display1"
- android:textSize="20sp"/>
+ android:textSize="14sp"
+ android:textAlignment="viewStart"/>
<TextView
android:id="@+id/total_summary"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:singleLine="true"
+ app:layout_constraintWidth_percent="0.45"
+ app:layout_constraintEnd_toStartOf="@id/custom_content"
android:ellipsize="marquee"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"/>
- </RelativeLayout>
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body1"
+ android:textSize="14sp"
+ android:textAlignment="viewEnd"/>
+ <FrameLayout
+ android:id="@+id/custom_content"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBottom_toBottomOf="@id/total_summary"
+ app:layout_constraintWidth_percent="0.1"/>
+ </androidx.constraintlayout.widget.ConstraintLayout>
<ProgressBar
android:id="@android:id/progress"
diff --git a/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java b/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
index 950a8b4ad7cc..af64a1dc2282 100644
--- a/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
+++ b/packages/SettingsLib/UsageProgressBarPreference/src/com/android/settingslib/widget/UsageProgressBarPreference.java
@@ -22,6 +22,9 @@ import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.RelativeSizeSpan;
import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -41,6 +44,7 @@ public class UsageProgressBarPreference extends Preference {
private CharSequence mUsageSummary;
private CharSequence mTotalSummary;
+ private ImageView mCustomImageView;
private int mPercent = -1;
/**
@@ -110,6 +114,15 @@ public class UsageProgressBarPreference extends Preference {
notifyChanged();
}
+ /** Set custom ImageView to the right side of total summary. */
+ public <T extends ImageView> void setCustomContent(T imageView) {
+ if (imageView == mCustomImageView) {
+ return;
+ }
+ mCustomImageView = imageView;
+ notifyChanged();
+ }
+
/**
* Binds the created View to the data for this preference.
*
@@ -141,6 +154,15 @@ public class UsageProgressBarPreference extends Preference {
progressBar.setIndeterminate(false);
progressBar.setProgress(mPercent);
}
+
+ final FrameLayout customLayout = (FrameLayout) holder.findViewById(R.id.custom_content);
+ if (mCustomImageView == null) {
+ customLayout.removeAllViews();
+ customLayout.setVisibility(View.GONE);
+ } else {
+ customLayout.addView(mCustomImageView);
+ customLayout.setVisibility(View.VISIBLE);
+ }
}
private CharSequence enlargeFontOfNumber(CharSequence summary) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index 5580afe70faf..78282fb14f5f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -19,6 +19,7 @@ import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
+import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
@@ -38,7 +39,9 @@ import android.util.FeatureFlagUtils;
import com.android.settingslib.R;
import com.android.settingslib.Utils;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* Track status of Wi-Fi for the Sys UI.
@@ -50,6 +53,7 @@ public class WifiStatusTracker {
private final NetworkScoreManager mNetworkScoreManager;
private final ConnectivityManager mConnectivityManager;
private final Handler mHandler = new Handler(Looper.getMainLooper());
+ private final Set<Integer> mNetworks = new HashSet<>();
private final WifiNetworkScoreCache.CacheListener mCacheListener =
new WifiNetworkScoreCache.CacheListener(mHandler) {
@Override
@@ -64,6 +68,20 @@ public class WifiStatusTracker {
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build();
private final NetworkCallback mNetworkCallback = new NetworkCallback() {
+ @Override
+ public void onAvailable(
+ Network network, NetworkCapabilities networkCapabilities,
+ LinkProperties linkProperties, boolean blocked) {
+ boolean isVcnOverWifi =
+ networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
+ && (Utils.tryGetWifiInfoForVcn(networkCapabilities) != null);
+ boolean isWifi =
+ networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
+ if (isVcnOverWifi || isWifi) {
+ mNetworks.add(network.getNetId());
+ }
+ }
+
// Note: onCapabilitiesChanged is guaranteed to be called "immediately" after onAvailable
// and onLinkPropertiesChanged.
@Override
@@ -84,9 +102,12 @@ public class WifiStatusTracker {
@Override
public void onLost(Network network) {
- updateWifiInfo(null);
- updateStatusLabel();
- mCallback.run();
+ if (mNetworks.contains(network.getNetId())) {
+ mNetworks.remove(network.getNetId());
+ updateWifiInfo(null);
+ updateStatusLabel();
+ mCallback.run();
+ }
}
};
private final NetworkCallback mDefaultNetworkCallback = new NetworkCallback() {
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java
index 85e2174bf87a..1a8477d9b86e 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/widget/UsageProgressBarPreferenceTest.java
@@ -18,11 +18,15 @@ package com.android.settingslib.widget;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+
import android.content.Context;
import android.text.SpannedString;
import android.text.style.RelativeSizeSpan;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -97,4 +101,30 @@ public class UsageProgressBarPreferenceTest {
.findViewById(android.R.id.progress);
assertThat(progressBar.getProgress()).isEqualTo((int) (31.0f / 80 * 100));
}
+
+ @Test
+ public void setCustomContent_setNullImageView_noChild() {
+ mUsageProgressBarPreference.setCustomContent(null /* imageView */);
+
+ mUsageProgressBarPreference.onBindViewHolder(mViewHolder);
+
+ final FrameLayout customContent =
+ (FrameLayout) mViewHolder.findViewById(R.id.custom_content);
+ assertThat(customContent.getChildCount()).isEqualTo(0);
+ assertThat(customContent.getVisibility()).isEqualTo(View.GONE);
+ }
+
+ @Test
+ public void setCustomContent_setImageView_oneChild() {
+ final ImageView imageView = mock(ImageView.class);
+ mUsageProgressBarPreference.setCustomContent(imageView);
+
+ mUsageProgressBarPreference.onBindViewHolder(mViewHolder);
+
+ final FrameLayout customContent =
+ (FrameLayout) mViewHolder.findViewById(R.id.custom_content);
+ assertThat(customContent.getChildCount()).isEqualTo(1);
+ assertThat(customContent.getChildAt(0)).isEqualTo(imageView);
+ assertThat(customContent.getVisibility()).isEqualTo(View.VISIBLE);
+ }
}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index efd941e3bd18..438cec8ef68f 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -272,6 +272,7 @@ public class SettingsBackupTest {
Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS,
Settings.Global.SMART_SUGGESTIONS_IN_NOTIFICATIONS_FLAGS,
Settings.Global.ENABLE_ADB_INCREMENTAL_INSTALL_DEFAULT,
+ Settings.Global.ENABLE_MULTI_SLOT_TIMEOUT_MILLIS,
Settings.Global.ENHANCED_4G_MODE_ENABLED,
Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
Settings.Global.ERROR_LOGCAT_PREFIX,
@@ -280,6 +281,7 @@ public class SettingsBackupTest {
Settings.Global.EUICC_UNSUPPORTED_COUNTRIES,
Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
Settings.Global.EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS,
+ Settings.Global.EUICC_SWITCH_SLOT_TIMEOUT_MILLIS,
Settings.Global.FANCY_IME_ANIMATIONS,
Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
Settings.Global.FORCED_APP_STANDBY_ENABLED,
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
index 80c8a285bfc6..35a2195accab 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -76,7 +76,7 @@
android:textSize="100dp"
android:includeFontPadding="false"
android:fontFamily="@font/clock"
- android:lineSpacingMultiplier=".65"
+ android:lineSpacingMultiplier=".7"
android:typeface="monospace"
android:elegantTextHeight="false"
dozeWeight="200"
@@ -97,7 +97,7 @@
android:gravity="center_horizontal"
android:textSize="@dimen/large_clock_text_size"
android:includeFontPadding="false"
- android:lineSpacingMultiplier=".65"
+ android:lineSpacingMultiplier=".7"
android:fontFamily="@font/clock"
android:typeface="monospace"
android:elegantTextHeight="false"
diff --git a/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml b/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml
index cf6413642c63..5cb6f4626b36 100644
--- a/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml
+++ b/packages/SystemUI/res/drawable/privacy_item_circle_camera.xml
@@ -21,16 +21,16 @@
>
<shape android:shape="oval">
<size
- android:height="28dp"
- android:width="28dp"
+ android:height="@dimen/ongoing_appops_dialog_circle_size"
+ android:width="@dimen/ongoing_appops_dialog_circle_size"
/>
<solid android:color="@color/privacy_circle_camera" />
</shape>
</item>
<item android:id="@id/icon"
android:gravity="center"
- android:width="20dp"
- android:height="20dp"
+ android:width="@dimen/ongoing_appops_dialog_icon_size"
+ android:height="@dimen/ongoing_appops_dialog_icon_size"
android:drawable="@*android:drawable/perm_group_camera"
/>
</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/privacy_item_circle_location.xml b/packages/SystemUI/res/drawable/privacy_item_circle_location.xml
index 0a6a4a31d0a5..28466c8a29b3 100644
--- a/packages/SystemUI/res/drawable/privacy_item_circle_location.xml
+++ b/packages/SystemUI/res/drawable/privacy_item_circle_location.xml
@@ -21,16 +21,16 @@
>
<shape android:shape="oval">
<size
- android:height="28dp"
- android:width="28dp"
+ android:height="@dimen/ongoing_appops_dialog_circle_size"
+ android:width="@dimen/ongoing_appops_dialog_circle_size"
/>
<solid android:color="@color/privacy_circle_microphone_location" />
</shape>
</item>
<item android:id="@id/icon"
android:gravity="center"
- android:width="20dp"
- android:height="20dp"
+ android:width="@dimen/ongoing_appops_dialog_icon_size"
+ android:height="@dimen/ongoing_appops_dialog_icon_size"
android:drawable="@*android:drawable/perm_group_microphone"
/>
</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml b/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml
index 0a6a4a31d0a5..28466c8a29b3 100644
--- a/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml
+++ b/packages/SystemUI/res/drawable/privacy_item_circle_microphone.xml
@@ -21,16 +21,16 @@
>
<shape android:shape="oval">
<size
- android:height="28dp"
- android:width="28dp"
+ android:height="@dimen/ongoing_appops_dialog_circle_size"
+ android:width="@dimen/ongoing_appops_dialog_circle_size"
/>
<solid android:color="@color/privacy_circle_microphone_location" />
</shape>
</item>
<item android:id="@id/icon"
android:gravity="center"
- android:width="20dp"
- android:height="20dp"
+ android:width="@dimen/ongoing_appops_dialog_icon_size"
+ android:height="@dimen/ongoing_appops_dialog_icon_size"
android:drawable="@*android:drawable/perm_group_microphone"
/>
</layer-list> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/privacy_dialog.xml b/packages/SystemUI/res/layout/privacy_dialog.xml
index 5db247e25d50..4d77a0d75689 100644
--- a/packages/SystemUI/res/layout/privacy_dialog.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog.xml
@@ -22,7 +22,13 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/ongoing_appops_dialog_side_margins"
android:layout_marginEnd="@dimen/ongoing_appops_dialog_side_margins"
+ android:layout_marginTop="8dp"
android:orientation="vertical"
- android:padding = "8dp"
+ android:paddingLeft="@dimen/ongoing_appops_dialog_side_padding"
+ android:paddingRight="@dimen/ongoing_appops_dialog_side_padding"
+ android:paddingBottom="12dp"
+ android:paddingTop="8dp"
android:background="@drawable/privacy_dialog_bg"
-/> \ No newline at end of file
+/>
+<!-- 12dp padding bottom so there's 20dp total under the icon -->
+<!-- 8dp padding top, as there's 4dp margin in each row --> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/privacy_dialog_item.xml b/packages/SystemUI/res/layout/privacy_dialog_item.xml
index 882e9680407e..91ffe225fac6 100644
--- a/packages/SystemUI/res/layout/privacy_dialog_item.xml
+++ b/packages/SystemUI/res/layout/privacy_dialog_item.xml
@@ -16,19 +16,22 @@
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/privacy_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:orientation="horizontal"
- android:layout_marginTop="8dp"
+ android:layout_marginTop="4dp"
+ android:importantForAccessibility="yes"
+ android:focusable="true"
>
+ <!-- 4dp marginTop makes 20dp minimum between icons -->
<ImageView
android:id="@+id/icon"
- android:layout_width="24dp"
- android:layout_height="24dp"
+ android:layout_width="@dimen/ongoing_appops_dialog_circle_size"
+ android:layout_height="@dimen/ongoing_appops_dialog_circle_size"
android:layout_gravity="center_vertical"
- android:layout_marginStart="12dp"
- android:layout_marginEnd="12dp"
+ android:importantForAccessibility="no"
/>
<TextView
@@ -38,25 +41,21 @@
android:layout_width="0dp"
android:layout_weight="1"
android:layout_gravity="center_vertical"
+ android:layout_marginStart="16dp"
+ android:layout_marginEnd="16dp"
+ android:textDirection="locale"
+ android:textAlignment="viewStart"
android:gravity="start | center_vertical"
- android:textAppearance="@style/TextAppearance.QS.TileLabel"
+ android:textAppearance="@style/TextAppearance.PrivacyDialog"
+ android:lineHeight="20sp"
/>
- <FrameLayout
- android:id="@+id/link"
- android:layout_width="48dp"
- android:layout_height="48dp"
+ <ImageView
+ android:layout_height="24dp"
+ android:layout_width="24dp"
android:layout_gravity="center_vertical"
- android:background="?android:attr/selectableItemBackground"
- >
-
- <ImageView
- android:layout_height="24dp"
- android:layout_width="24dp"
- android:layout_gravity="center"
- android:src="@*android:drawable/ic_chevron_end"
- android:tint="?android:attr/textColorPrimary"
- />
- </FrameLayout>
+ android:src="@*android:drawable/ic_chevron_end"
+ android:tint="?android:attr/textColorPrimary"
+ />
</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 6dcb50240262..5db7c25835c8 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Skermopname"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Begin"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Om voort te gaan, moet &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; toegang tot jou toestel se mikrofoon hê."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Om voort te gaan, moet &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; toegang tot jou toestel se kamera hê."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Toestel"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Swiep op om programme te wissel"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Sleep regs om programme vinnig te wissel"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tik weer om oop te maak"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swiep op om oop te maak"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swiep op om weer te probeer"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontsluit om NFC te gebruik"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Hierdie toestel behoort aan jou organisasie"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Hierdie toestel behoort aan <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Swiep vanaf ikoon vir foon"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programme gebruik tans jou <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" en "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> gebruik tans die <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> het onlangs die <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> gebruik"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(onderneming)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Oproep"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(deur <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ligging"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoon"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index d1954a6f6179..1af18fee0fb9 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"መተግበሪያዎች የእርስዎን <xliff:g id="TYPES_LIST">%s</xliff:g> እየተጠቀሙ ነው።"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"፣ "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" እና "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>ን እየተጠቀመ ነው"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> በቅርብ ጊዜ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>ን ይጠቀማል።"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ድርጅት)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"የስልክ ጥሪ"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(እስከ <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ካሜራ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"አካባቢ"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ማይክሮፎን"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index f2652d3c66c2..b34b39a765b1 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -424,10 +424,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"تسجيل الشاشة"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"بدء"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"إيقاف"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"‏للمتابعة، يحتاج تطبيق &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; إلى الوصول إلى ميكروفون الجهاز."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"‏للمتابعة، يحتاج تطبيق &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; إلى الوصول إلى كاميرا الجهاز."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"الجهاز"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"مرّر سريعًا لأعلى لتبديل التطبيقات"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"اسحب لليسار للتبديل السريع بين التطبيقات"</string>
@@ -450,8 +448,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"انقر مرة أخرى للفتح"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"يمكنك الفتح بالتمرير سريعًا لأعلى."</string>
<string name="keyguard_retry" msgid="886802522584053523">"مرِّر سريعًا للأعلى لإعادة المحاولة."</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏يجب فتح قفل الشاشة لاستخدام تقنية الاتصال قصير المدى (NFC)."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"هذا الجهاز يخص مؤسستك."</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"هذا الجهاز يخص <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
<string name="phone_hint" msgid="6682125338461375925">"يمكنك التمرير سريعًا من الرمز لتشغيل الهاتف"</string>
@@ -990,6 +987,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"تستخدم التطبيقات <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" و "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"يستخدم تطبيق <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> عملية <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> الآن."</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"استخدَم تطبيق <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> عملية <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> مؤخرًا."</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(للمؤسسات)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"مكالمة هاتفية"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(من خلال <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"الكاميرا"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"الموقع"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"الميكروفون"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 8abb5edc233e..88b2bb278995 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"এপ্লিকেশ্বনসমূহে আপোনাৰ <xliff:g id="TYPES_LIST">%s</xliff:g> ব্যৱহাৰ কৰি আছে।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" আৰু "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>এ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ব্যৱহাৰ কৰি আছে"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>এ শেহতীয়াকৈ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ব্যৱহাৰ কৰিছে"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(এণ্টাৰপ্ৰাইজ)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g>ৰ জৰিয়তে)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"কেমেৰা"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"অৱস্থান"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"মাইক্ৰ\'ফ\'ন"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 352282c3b8f8..6f1c347a5987 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Ekran yazması"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Başlayın"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Dayandırın"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Davam etmək üçün &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; tətbiqi cihazın mikrofonuna giriş tələb edir."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Davam etmək üçün &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; tətbiqi cihazın kamerasına giriş tələb edir."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Cihaz"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Tətbiqi dəyişmək üçün yuxarı sürüşdürün"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Tətbiqləri cəld dəyişmək üçün sağa çəkin"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Açmaq üçün yenidən tıklayın"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Açmaq üçün yuxarı sürüşdürün"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Yenidən cəhd etmək üçün yuxarı sürüşdürün"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC istifadə etmək üçün kiliddən çıxarın"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz təşkilatınıza məxsusdur"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> təşkilatına məxsusdur"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telefon üçün ikonadan sürüşdürün"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Tətbiqlər <xliff:g id="TYPES_LIST">%s</xliff:g> istifadə edir."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" və "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> istifadə edir"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> bu yaxınlarda <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> istifadə edib"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(korporativ)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefon zəngi"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> vasitəsilə)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"məkan"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index ba131c49329e..2185a66477a0 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -418,10 +418,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Snimak ekrana"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Počnite"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavite"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; zahteva pristup mikrofonu uređaja radi nastavljanja."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; zahteva pristup kameri uređaja radi nastavljanja."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Uređaj"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Prevucite nagore da biste menjali aplikacije"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Prevucite udesno da biste brzo promenili aplikacije"</string>
@@ -444,8 +442,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite ponovo da biste otvorili"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prevucite nagore da biste otvorili"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Prevucite nagore da biste probali ponovo"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste koristili NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada organizaciji"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Prevucite od ikone za telefon"</string>
@@ -975,6 +972,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> koristi: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> je nedavno koristila: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(za preduzeća)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonski poziv"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(preko: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 61f71885c501..e5356ae6486c 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -420,10 +420,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Запіс экрана"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Пачаць"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Спыніць"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Каб працягнуць, дайце праграме &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ да мікрафона прылады."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Каб працягнуць, дайце праграме &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ да камеры прылады."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Прылада"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Правядзіце ўверх, каб пераключыць праграмы"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Каб хутка пераключыцца паміж праграмамі, перацягніце ўправа"</string>
@@ -446,8 +444,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Дакраніцеся яшчэ раз, каб адкрыць"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Каб адкрыць, прагарніце ўверх"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Прагартайце ўверх, каб паўтарыць спробу"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Разблакіруйце, каб выкарыстоўваць NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Гэта прылада належыць вашай арганізацыі"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Гэта прылада належыць арганізацыі \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
<string name="phone_hint" msgid="6682125338461375925">"Тэлефон: правядзіце пальцам ад значка"</string>
@@ -980,6 +977,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Праграмы выкарыстоўваюць: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" і "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Праграма \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\" выкарыстоўвае праграму \"<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>\""</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Праграма \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\" нядаўна выкарыстоўвала праграму \"<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>\""</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(прадпрыемства)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Тэлефонны выклік"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(праз праграму \"<xliff:g id="ATTRIBUTION">%s</xliff:g>\")"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"геалакацыя"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"мікрафон"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index d6ba258cd1a9..adf852b5495b 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Записване на екрана"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Старт"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Стоп"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"За да продължите, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; се нуждае от достъп до микрофона на устройството ви."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"За да продължите, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; се нуждае от достъп до камерата на устройството ви."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Устройство"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Прекарайте пръст нагоре, за да превключите между приложенията"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Плъзнете надясно за бързо превключване между приложенията"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Докоснете отново, за да отворите"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Прекарайте пръст нагоре, за да отключите"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Плъзнете бързо нагоре, за да опитате отново"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отключете, за да използвате NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Това устройство принадлежи на организацията ви"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Това устройство принадлежи на <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Плъзнете с пръст от иконата, за да използвате телефона"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Някои приложения използват <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> използва <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> наскоро използва <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(корпоративна версия)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Телефонно обаждане"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(чрез <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камерата"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"местополож."</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофона"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 14c77796738c..437abb85b445 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"স্ক্রিন রেকর্ড"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"শুরু করুন"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"বন্ধ করুন"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"চালিয়ে যেতে, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; আপনার ডিভাইসের মাইক্রোফোন অ্যাক্সেস করতে চায়।"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"চালিয়ে যেতে, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; আপনার ডিভাইসের ক্যামেরা অ্যাক্সেস করতে চায়।"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"ডিভাইস"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"অন্য অ্যাপে যেতে উপরের দিকে সোয়াইপ করুন"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"একটি অ্যাপ ছেড়ে দ্রুত অন্য অ্যাপে যেতে ডান দিকে টেনে আনুন"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"খোলার জন্য আবার আলতো চাপুন"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"খোলার জন্য উপরে সোয়াইপ করুন"</string>
<string name="keyguard_retry" msgid="886802522584053523">"আবার চেষ্টা করতে উপরের দিকে সোয়াইপ করুন"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ব্যবহার করতে আনলক করুন"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"এই ডিভাইসটি <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-এর"</string>
<string name="phone_hint" msgid="6682125338461375925">"ফোনের জন্য আইকন থেকে সোয়াইপ করুন"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"অ্যাপ্লিকেশনগুলি আপনার <xliff:g id="TYPES_LIST">%s</xliff:g> ব্যবহার করছে।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" এবং "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> এখন <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ব্যবহার করছে"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> সম্প্রতি <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ব্যবহার করেছে"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"এন্টারপ্রাইজ"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ফোনকল"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g>-এর মাধ্যমে)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ক্যামেরা"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"লোকেশন"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"মাইক্রোফোন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index d2f0c0d9aaac..f2b3edca02de 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -972,6 +972,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> koristi aplikaciju <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> je nedavno koristila aplikaciju <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(preduzeće)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonski poziv"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(putem aplikacije <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kameru"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 1cc7288344d4..bdcde318179a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Gravació de pantalla"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Inicia"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Atura"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Per continuar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; necessita accedir al micròfon del dispositiu."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Per continuar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; necessita accedir a la càmera del dispositiu."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Dispositiu"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Llisca cap amunt per canviar d\'aplicació"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrossega el dit cap a la dreta per canviar ràpidament d\'aplicació"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Torna a tocar per obrir-la."</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Llisca cap amunt per obrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Llisca cap a dalt per tornar-ho a provar"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloqueja per utilitzar l\'NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Aquest dispositiu pertany a la teva organització"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Aquest dispositiu pertany a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Llisca des de la icona per obrir el telèfon"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Algunes aplicacions estan fent servir el següent: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> està utilitzant: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Recentment <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ha utilitzat: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresa)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Trucada"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(a través de: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"càmera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ubicació"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"micròfon"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 13fe67644409..aa5a1dd70695 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -420,10 +420,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Záznam obrazovky"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Spustit"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Ukončit"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Než budete pokračovat, udělte aplikaci &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; přístup k mikrofonu na zařízení."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Než budete pokračovat, udělte aplikaci &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; přístup k fotoaparátu na zařízení."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Zařízení"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Přejetím nahoru přepnete aplikace"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Přetažením doprava rychle přepnete aplikace"</string>
@@ -446,8 +444,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Oznámení otevřete opětovným klepnutím"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Otevřete přejetím prstem nahoru"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Přejetím nahoru to zkusíte znovu"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC vyžaduje odemknutou obrazovku"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zařízení patří vaší organizaci"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Toto zařízení patří organizaci <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telefon otevřete přejetím prstem od ikony"</string>
@@ -980,6 +977,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikace využívají tato oprávnění: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" a "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikace <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> používá aplikaci <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikace <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> nedávno použila aplikaci <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(podniková verze)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonní hovor"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(prostřednictvím aplikace <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparát"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"poloha"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 18dfc0651a70..5630293c1606 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Optag skærm"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Start"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; skal have adgang til din enheds mikrofon, før den kan fortsætte."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; skal have adgang til din enheds kamera, før den kan fortsætte."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Enhed"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Stryg opad for at skifte apps"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Træk til højre for hurtigt at skifte app"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tryk igen for at åbne"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Stryg opad for at åbne"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Stryg opad for at prøve igen"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås op for at bruge NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enhed tilhører din organisation"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Denne enhed tilhører <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Stryg fra telefonikonet"</string>
@@ -784,7 +781,7 @@
<string name="keyboard_key_tab" msgid="4592772350906496730">"Tab"</string>
<string name="keyboard_key_space" msgid="6980847564173394012">"Mellemrumstast"</string>
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
- <string name="keyboard_key_backspace" msgid="4095278312039628074">"Tilbagetast"</string>
+ <string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Afspil/pause"</string>
<string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Næste"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps anvender enhedens <xliff:g id="TYPES_LIST">%s</xliff:g>"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> anvender <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> anvendte <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> for nylig"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(til virksomhedsbrug)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonopkald"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(via <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"placering"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 8485e8447c22..e2468bf04505 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Bildschirmaufnahme"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Starten"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Beenden"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Zum Fortfahren benötigt, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; Zugriff auf das Mikrofon deines Geräts."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Zum Fortfahren benötigt &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; Zugriff auf die Kamera deines Geräts."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Gerät"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Nach oben wischen, um Apps zu wechseln"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Zum schnellen Wechseln der Apps nach rechts ziehen"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Erneut tippen, um Benachrichtigung zu öffnen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Zum Öffnen nach oben wischen"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Zum Wiederholen nach oben wischen"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Zur Verwendung von NFC entsperren"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Dieses Gerät gehört deiner Organisation"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Dieses Gerät gehört <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Zum Öffnen des Telefons vom Symbol wegwischen"</string>
@@ -970,6 +967,16 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps verwenden gerade Folgendes: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" und "</string>
+ <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) -->
+ <skip />
<string name="privacy_type_camera" msgid="7974051382167078332">"Kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"Standort"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"Mikrofon"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index f21a9c9d0468..aa747f24a8df 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Εγγραφή οθόνης"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Έναρξη"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Διακοπή"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Για να συνεχίσετε, η εφαρμογή &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&amp;gt, χρειάζεται πρόσβαση στο μικρόφωνο της συσκευής σας."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Για να συνεχίσετε, η εφαρμογή &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; χρειάζεται πρόσβαση στην κάμερα της συσκευής σας."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Συσκευή"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Σύρετε προς τα επάνω για εναλλαγή των εφαρμογών"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Σύρετε προς τα δεξιά για γρήγορη εναλλαγή εφαρμογών"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Πατήστε ξανά για να ανοίξετε"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Σύρετε προς τα επάνω για άνοιγμα"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Σύρετε προς τα πάνω για να δοκιμάσετε ξανά"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ξεκλείδωμα για χρήση του NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Αυτή η συσκευή ανήκει στον οργανισμό σας."</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Αυτή η συσκευή ανήκει στον οργανισμό <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Σύρετε προς τα έξω για τηλέφωνο"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Οι εφαρμογές χρησιμοποιούν τις λειτουργίες <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" και "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Χρήση <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> από την εφαρμογή <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Πρόσφατη χρήση <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> από την εφαρμογή <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(για επιχειρήσεις)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Τηλεφωνική κλήση"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(μέσω <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"κάμερα"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"τοποθεσία"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"μικρόφωνο"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 4ae38f584303..88a40c346e79 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> is using the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> used the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recently"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(through <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index ff5e873e5435..bf7883af8138 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> is using the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> used the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recently"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(through <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 4ae38f584303..88a40c346e79 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> is using the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> used the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recently"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(through <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 4ae38f584303..88a40c346e79 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" and "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> is using the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> used the <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recently"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(through <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"location"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index cddd75e48d27..a14566ac0c1a 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‎Applications are using your ‎‏‎‎‏‏‎<xliff:g id="TYPES_LIST">%s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‎, ‎‏‎‎‏‎ "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‎ "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is using the ‎‏‎‎‏‏‎<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ used the ‎‏‎‎‏‏‎<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎ recently‎‏‎‎‏‎"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎(enterprise)‎‏‎‎‏‎"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‏‏‏‎Phonecall‎‏‎‎‏‎"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‏‏‎‎(through ‎‏‎‎‏‏‎<xliff:g id="ATTRIBUTION">%s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎camera‎‏‎‎‏‎"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎location‎‏‎‎‏‎"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‎microphone‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 021d944f6aec..4b482b914164 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hay aplicaciones que están usando tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" y "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está usando <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> usó <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recientemente"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresarial)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Teléfono"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(a través de <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"cámara"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ubicación"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"micrófono"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 584116e263f8..36fee3f89da9 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Grabar pantalla"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Detener"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Para continuar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; necesita tener acceso al micrófono del dispositivo."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Para continuar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; necesita tener acceso a la cámara del dispositivo."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Dispositivo"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Desliza el dedo hacia arriba para cambiar de aplicación"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrastra hacia la derecha para cambiar rápidamente de aplicación"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toca de nuevo para abrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Desliza el dedo hacia arriba para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Desliza el dedo hacia arriba para volverlo a intentar"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquear para usar NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertenece a tu organización"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertenece a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Desliza desde el icono para abrir el teléfono"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hay aplicaciones que usan tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" y "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está usando este elemento: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ha usado recientemente este elemento: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresa)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Llamada telefónica"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(a través de <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"cámara"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ubicación"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"micrófono"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 72c6907353b0..ff043e0872af 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Ekraanisalvestus"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Alustage"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Peatage"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Jätkamiseks vajab rakendus &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; juurdepääsu teie seadme mikrofonile."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Jätkamiseks vajab rakendus &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; juurdepääsu teie seadme kaamerale."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Seade"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Rakenduste vahetamiseks pühkige üles"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Lohistage paremale, et rakendusi kiiresti vahetada"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Avamiseks puudutage uuesti"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pühkige avamiseks üles"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Uuesti proovimiseks pühkige üles"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC kasutamiseks avage."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"See seade kuulub teie organisatsioonile"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Selle seadme omanik on <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telefoni kasutamiseks pühkige ikoonilt eemale"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Rakendused kasutavad järgmisi: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ja "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> kasutab järgmist: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> kasutas hiljuti järgmist: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ettevõte)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonikõne"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(üksuse <xliff:g id="ATTRIBUTION">%s</xliff:g> kaudu)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kaamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"asukoht"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index ab26b92b2fae..7517f17623fc 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Pantaila-grabaketa"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Hasi"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Gelditu"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Aurrera egiteko, gailuaren mikrofonoa atzitzeko baimena behar du &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; aplikazioak."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Aurrera egiteko, gailuaren kamera atzitzeko baimena behar du &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; aplikazioak."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Gailua"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Egin gora aplikazioa aldatzeko"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrastatu eskuinera aplikazioa azkar aldatzeko"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Irekitzeko, ukitu berriro"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pasatu hatza gora irekitzeko"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Berriro saiatzeko, pasatu hatza gora"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desblokeatu NFC erabiltzeko"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Gailu hau zure erakundearena da"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Gailu hau <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> erakundearena da"</string>
<string name="phone_hint" msgid="6682125338461375925">"Pasatu hatza ikonotik, telefonoa irekitzeko"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikazio batzuk <xliff:g id="TYPES_LIST">%s</xliff:g> erabiltzen ari dira."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" eta "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> aplikazioa <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> erabiltzen ari da"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> aplikazioak <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> erabili du duela gutxi"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enpresa)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefono-deia"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> aplikazioaren bidez)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"kokapena"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonoa"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index dccea5a5c84b..231eb45fef64 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"برنامه‌ها از <xliff:g id="TYPES_LIST">%s</xliff:g> شما استفاده می‌‌کنند."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" و "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> درحال استفاده از <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> است"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> اخیراً از <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> استفاده کرده است"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(شرکتی)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(ازطریق <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"دوربین"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"مکان"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"میکروفون"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 5b43cf94c166..a6c43d96ae81 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Tallennus"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Aloita"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Lopeta"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Jotta voit jatkaa, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; tarvitsee pääsyn laitteesi mikrofoniin."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Jotta voit jatkaa, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; tarvitsee pääsyn laitteesi kameraan."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Laite"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Vaihda sovellusta pyyhkäisemällä ylös"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Vaihda sovellusta nopeasti vetämällä oikealle"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Avaa napauttamalla uudelleen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Avaa pyyhkäisemällä ylös"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Yritä uudelleen pyyhkäisemällä ylös"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Avaa lukitus käyttääksesi NFC:tä"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Organisaatiosi omistaa tämän laitteen"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> omistaa tämän laitteen"</string>
<string name="phone_hint" msgid="6682125338461375925">"Avaa puhelu pyyhkäisemällä."</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"<xliff:g id="TYPES_LIST">%s</xliff:g> ovat sovellusten käytössä."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ja "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> käyttää kohdetta <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> käytti kohdetta <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> äskettäin"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(yritys)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Puhelu"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(kautta: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"sijainti"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoni"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 2e36a92d073a..07f8af5ad4e2 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" et "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> utilise cet élément : <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> a récemment utilisé cet élément : <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(entreprise)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Appel téléphonique"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(par l\'intermédiaire de <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"appareil photo"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"position"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microphone"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index b8a70ee62545..7bbbff668710 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Enregistrement de l\'écran"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Démarrer"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Arrêter"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Pour continuer, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; a besoin d\'accéder au micro de votre appareil."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Pour continuer, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; a besoin d\'accéder à l\'appareil photo de votre appareil."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Appareil"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Balayer l\'écran vers le haut pour changer d\'application"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Déplacer vers la droite pour changer rapidement d\'application"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Appuyer à nouveau pour ouvrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Balayer vers le haut pour ouvrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Balayez l\'écran vers le haut pour réessayer"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Déverrouillez l\'écran pour pouvoir utiliser NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Cet appareil appartient à votre organisation"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Cet appareil appartient à <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Balayer pour téléphoner"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" et "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> utilise <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> a utilisé <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> récemment"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(Enterprise)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Appel téléphonique"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(via <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"appareil photo"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"position"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"micro"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 40a514e25b95..0ac82616c4aa 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Gravación da pantalla"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Deter"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Para continuar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa acceder ao micrófono do dispositivo."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Para continuar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; precisa acceder á cámara do dispositivo."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Dispositivo"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Pasar o dedo cara arriba para cambiar de aplicación"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Arrastra cara á dereita para cambiar de aplicacións rapidamente"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Toca de novo para abrir"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Pasa o dedo cara arriba para abrir"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Pasa o dedo cara arriba para tentalo de novo"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Desbloquea o dispositivo para utilizar a NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Este dispositivo pertence á túa organización"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Este dispositivo pertence a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Pasa o dedo desde a icona para acceder ao teléfono"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Hai aplicacións que están utilizando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está utilizando a aplicación <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> utilizou recentemente a aplicación <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(versión empresarial)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Chamada de teléfono"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(mediante <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"a cámara"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"a localiz."</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"o micrófono"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 2c37ce76d49b..f4e13332a34a 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"સ્ક્રીન રેકૉર્ડ કરો"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"શરૂ કરો"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"રોકો"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"ચાલુ રાખવા માટે, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;ને તમારા ડિવાઇસના માઇક્રોફોનના ઍક્સેસની જરૂર છે."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"ચાલુ રાખવા માટે, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;ને તમારા ડિવાઇસના કૅમેરાના ઍક્સેસની જરૂર છે."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"ડિવાઇસ"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ઍપ સ્વિચ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ઍપને ઝડપથી સ્વિચ કરવા માટે જમણે ખેંચો"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ખોલવા માટે ફરીથી ટૅપ કરો"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ખોલવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ફરી પ્રયાસ કરવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCનો ઉપયોગ કરવા માટે અનલૉક કરો"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"આ ડિવાઇસ તમારી સંસ્થાની માલિકીનું છે"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"આ ડિવાઇસ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>ની માલિકીનું છે"</string>
<string name="phone_hint" msgid="6682125338461375925">"ફોન માટે આયકનમાંથી સ્વાઇપ કરો"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ઍપ્લિકેશન તમારા <xliff:g id="TYPES_LIST">%s</xliff:g>નો ઉપયોગ કરી રહી છે."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" અને "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>નો ઉપયોગ કરી રહી છે"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>એ તાજેતરમાં જ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>નો ઉપયોગ કર્યો છે"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(એન્ટરપ્રાઇઝ)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ફોન કૉલ"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> મારફતે)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"કૅમેરા"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"સ્થાન"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"માઇક્રોફોન"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index af9bf1e2c19d..50b078f97ccb 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -418,10 +418,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"स्क्रीन रिकॉर्ड"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"शुरू करें"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"रोकें"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"जारी रखने के लिए, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; को आपके डिवाइस का माइक्रोफ़ोन ऐक्सेस करने की ज़रूरत है."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"जारी रखने के लिए, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; को आपके डिवाइस का कैमरा ऐक्सेस करने की ज़रूरत है."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"डिवाइस"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ऐप्लिकेशन बदलने के लिए ऊपर स्वाइप करें"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ऐप्लिकेशन को झटपट स्विच करने के लिए उसे दाईं ओर खींचें और छोड़ें"</string>
@@ -444,8 +442,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"खोलने के लिए फिर से टैप करें"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"खोलने के लिए ऊपर स्वाइप करें"</string>
<string name="keyguard_retry" msgid="886802522584053523">"फिर से कोशिश करने के लिए ऊपर की ओर स्वाइप करें"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"एनएफ़सी इस्तेमाल करने के लिए, स्क्रीन को अनलॉक करें"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"इस डिवाइस का मालिकाना हक <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> के पास है"</string>
<string name="phone_hint" msgid="6682125338461375925">"फ़ोन के लिए आइकॉन से स्वाइप करें"</string>
@@ -972,6 +969,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ऐप्लिकेशन आपकी <xliff:g id="TYPES_LIST">%s</xliff:g> का इस्तेमाल कर रहे हैं."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" और "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> का इस्तेमाल कर रहा है"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ने हाल ही में <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> का इस्तेमाल किया"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"एंटरप्राइज़ वर्शन"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"<xliff:g id="ATTRIBUTION">%s</xliff:g> के ज़रिए"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"कैमरा"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"जगह"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"माइक्रोफ़ोन"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 73e13499b1bc..c80f26260fca 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -418,10 +418,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Snimač zaslona"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Početak"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavi"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Da bi nastavila s radom, aplikacija &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; treba pristupiti mikrofonu vašeg uređaja."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Da bi nastavila s radom, aplikacija &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; treba pristupiti fotoaparatu vašeg uređaja."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Uređaj"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Prijeđite prstom prema gore da biste promijenili aplikaciju"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Povucite udesno da biste brzo promijenili aplikaciju"</string>
@@ -444,8 +442,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Dodirnite opet za otvaranje"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Prijeđite prstom prema gore da biste otvorili"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Prijeđite prstom prema gore za ponovni pokušaj"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Otključajte da biste upotrijebili NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Ovaj uređaj pripada vašoj organizaciji"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Ovaj uređaj pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Prijeđite prstom od ikone za telefon"</string>
@@ -975,6 +972,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije upotrebljavaju <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> koristi sljedeće: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> nedavno je koristila sljedeće: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(za poslovne korisnike)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonski poziv"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(putem aplikacije <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c947754be25a..868b2e7cbbb0 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Képernyő rögzítése"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Indítás"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Leállítás"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"A folytatáshoz a(z) &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; alkalmazásnak hozzáférésre van szüksége az eszköze mikrofonjához."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"A folytatáshoz a(z) &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; alkalmazásnak hozzáférésre van szüksége az eszköze kamerájához."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Eszköz"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Váltás az alkalmazások között felfelé csúsztatással"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Húzza jobbra az ujját az alkalmazások közötti gyors váltáshoz"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Koppintson ismét a megnyitáshoz"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Csúsztasson felfelé a megnyitáshoz"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Az újrapróbálkozáshoz csúsztassa felfelé az ujját"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Az NFC használatához oldja fel a képernyőzárat"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Ez az eszköz az Ön szervezetének tulajdonában van"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Ez az eszköz a(z) <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tulajdonában van"</string>
<string name="phone_hint" msgid="6682125338461375925">"A telefonhoz csúsztasson az ikonról"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Több alkalmazás használja a következőket: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" és "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"A(z) <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> használja a következőt: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"A(z) <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> nemrég használta a következőt: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(vállalati)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonhívás"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(a következőn keresztül: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"helyadatok"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 1ef540c05e75..3c088749ed57 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Էկրանի ձայնագրում"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Սկսել"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Կանգնեցնել"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Շարունակելու համար &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; հավելվածին անհրաժեշտ է ձեր սարքի խոսափողի օգտագործման թույլտվություն։"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Շարունակելու համար &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; հավելվածին անհրաժեշտ է ձեր սարքի տեսախցիկի օգտագործման թույլտվություն։"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Սարք"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Սահեցրեք վերև՝ մյուս հավելվածին անցնելու համար"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Քաշեք աջ՝ հավելվածների միջև անցնելու համար"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Կրկին հպեք՝ բացելու համար"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Բացելու համար սահեցրեք վերև"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Սահեցրեք վերև՝ նորից փորձելու համար"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ապակողպեք՝ NFC-ն օգտագործելու համար"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Այս սարքը պատկանում է ձեր կազմակերպությանը"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Այս սարքը պատկանում է «<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>» կազմակերպությանը"</string>
<string name="phone_hint" msgid="6682125338461375925">"Սահահարվածեք հեռախոսի պատկերակից"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Հավելվածներն օգտագործում են ձեր <xliff:g id="TYPES_LIST">%s</xliff:g>:"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" և "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> հավելվածն օգտագործում է «<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>» գործառույթը"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> հավելվածը վերջերս օգտագործել է «<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>» գործառույթը"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(կորպորատիվ տարբերակ)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Հեռախոսազանգ"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g>-ի միջոցով)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"տեսախցիկը"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"վայրը"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"խոսափողը"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 0de7efa85607..a5d8a27cf5a0 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Rekaman Layar"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Mulai"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Berhenti"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Untuk melanjutkan, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; memerlukan akses ke mikrofon perangkat."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Untuk melanjutkan, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; memerlukan akses ke kamera perangkat."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Perangkat"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Geser ke atas untuk beralih aplikasi"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Tarik ke kanan untuk beralih aplikasi dengan cepat"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ketuk lagi untuk membuka"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Geser ke atas untuk membuka"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Geser ke atas untuk mencoba lagi"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Perangkat ini milik organisasi Anda"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Perangkat ini milik <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Geser dari ikon untuk telepon"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikasi menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dan "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> sedang menggunakan <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> menggunakan <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> baru-baru ini"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(perusahaan)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Panggilan telepon"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(melalui <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokasi"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 777479d4da1f..5f794e76150f 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Skjáupptaka"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Hefja"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stöðva"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Til að halda áfram þarf &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; aðgang að hljóðnema tækisins."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Til að halda áfram þarf &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; aðgang að myndavél tækisins."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Tæki"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Strjúktu upp til að skipta á milli forrita"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Dragðu til hægri til að skipta hratt á milli forrita"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ýttu aftur til að opna"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Strjúktu upp til að opna"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Strjúktu upp til að reyna aftur"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Taktu úr lás til að nota NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Þetta tæki tilheyrir fyrirtækinu þínu"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Þetta tæki tilheyrir <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Strjúktu frá tákninu fyrir síma"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Forrit eru að nota <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> er að nota <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> notaði <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> nýlega"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(fyrirtæki)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Símtal"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(í gegnum <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"myndavél"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"staðsetning"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"hljóðnemi"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 2af2d5f4344e..cfd07970b0cd 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Registrazione schermo"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Inizia"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Interrompi"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Per continuare, l\'app &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; deve accedere al microfono del dispositivo."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Per continuare, l\'app &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; deve accedere alla videocamera del dispositivo."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Dispositivo"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Scorri verso l\'alto per passare ad altre app"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Trascina verso destra per cambiare velocemente app"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tocca ancora per aprire"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Scorri verso l\'alto per aprire"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Scorri verso l\'alto per riprovare"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Sblocca per usare NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Questo dispositivo appartiene alla tua organizzazione"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Questo dispositivo appartiene a <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Scorri per accedere al telefono"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Le app stanno usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> sta usando: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ha usato di recente: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(tramite <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"Fotocamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"luogo"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"un microfono"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index e8a1ede7d39f..c4d088d24cce 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -420,10 +420,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"הקלטת המסך"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"התחלה"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"עצירה"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"‏כדי להמשיך, האפליקציה &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; צריכה גישה למיקרופון של המכשיר שלך."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"‏כדי להמשיך, האפליקציה &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; צריכה גישה למצלמה של המכשיר שלך."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"מכשיר"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"יש להחליק מעלה כדי להחליף אפליקציות"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"יש לגרור ימינה כדי לעבור במהירות בין אפליקציות"</string>
@@ -446,8 +444,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"הקש שוב כדי לפתוח"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"צריך להחליק כדי לפתוח"</string>
<string name="keyguard_retry" msgid="886802522584053523">"יש להחליק למעלה כדי לנסות שוב"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏יש לבטל נעילה כדי להשתמש ב-NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"המכשיר הזה שייך לארגון שלך"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"המכשיר הזה שייך לארגון <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"החלק מהסמל כדי להפעיל את הטלפון"</string>
@@ -980,6 +977,16 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"אפליקציות משתמשות ב<xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" וגם "</string>
+ <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) -->
+ <skip />
<string name="privacy_type_camera" msgid="7974051382167078332">"מצלמה"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"מיקום"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"מיקרופון"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index e15366c5f37a..3fcc7138d9b3 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"スクリーン レコード"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"開始"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"停止"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"続行するには、&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; にデバイスのマイクへのアクセスを許可する必要があります。"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"続行するには、&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; にデバイスのカメラへのアクセスを許可する必要があります。"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"デバイス"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"アプリを切り替えるには上にスワイプ"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"右にドラッグするとアプリを素早く切り替えることができます"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"開くにはもう一度タップしてください"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"開くには上にスワイプします"</string>
<string name="keyguard_retry" msgid="886802522584053523">"上にスワイプしてもう一度お試しください"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC を使用するには、ロックを解除してください"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"これは組織が所有するデバイスです"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"これは <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> が所有するデバイスです"</string>
<string name="phone_hint" msgid="6682125338461375925">"右にスワイプして通話"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"アプリは<xliff:g id="TYPES_LIST">%s</xliff:g>を使用しています。"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 、 "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> は <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> を使用しています"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> は最近 <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> を使用しました"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(エンタープライズ版)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"電話"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> 経由)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"カメラ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"現在地情報"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"マイク"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 386847e198ea..5c11fa44f3fc 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"ეკრანის ჩანაწერი"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"დაწყება"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"შეწყვეტა"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"გასაგრძელებლად &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;-ს თქვენი მოწყობილობის მიკროფონზე წვდომა სჭირდება."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"გასაგრძელებლად &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;-ს თქვენი მოწყობილობის კამერაზე წვდომა სჭირდება."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"მოწყობილობა"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"გადაფურცლეთ ზემოთ აპების გადასართავად"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"აპების სწრაფად გადასართავად ჩავლებით გადაიტანეთ მარჯვნივ"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"შეეხეთ ისევ გასახსნელად"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"გასახსნელად გადაფურცლეთ ზემოთ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ხელახლა საცდელად გადაფურცლეთ ზემოთ"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"განბლოკეთ NFC-ის გამოსაყენებლად"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"ამ მოწყობილობას ფლობს <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"ტელეფონისთვის გადაფურცლეთ ხატულადან"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"აპლიკაციების მიერ გამოიყენება თქვენი <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" და "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> იყენებს აპს <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"აპმა <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ახლახან გამოიყენა <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(კორპორაციული)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"სატელეფონო ზარი"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(აპის <xliff:g id="ATTRIBUTION">%s</xliff:g> მეშვეობით)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"კამერა"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"მდებარეობა"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"მიკროფონი"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index db318eadc1b9..89f905733fa6 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -285,8 +285,8 @@
<string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"Жұмыс режимі қосулы."</string>
<string name="accessibility_quick_settings_work_mode_changed_off" msgid="6256690740556798683">"Жұмыс режимі өшірілді."</string>
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"Жұмыс режимі қосылды."</string>
- <string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"Data Saver өшірілді."</string>
- <string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"Data Saver қосылды."</string>
+ <string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"Трафикті үнемдеу режимі өшірілді."</string>
+ <string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"Трафикті үнемдеу режимі қосылды."</string>
<string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="7608378211873807353">"Sensor Privacy функциясы өшірулі."</string>
<string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="4267393685085328801">"Sensor Privacy функциясы қосулы."</string>
<string name="accessibility_brightness" msgid="5391187016177823721">"Дисплей жарықтығы"</string>
@@ -383,7 +383,7 @@
<string name="quick_settings_tethering_label" msgid="5257299852322475780">"Тетеринг"</string>
<string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Хотспот"</string>
<string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Қосылуда…"</string>
- <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Data Saver қосулы"</string>
+ <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Трафикті үнемдеу режимі қосулы"</string>
<plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
<item quantity="other">%d құрылғы</item>
<item quantity="one">%d құрылғы</item>
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Экранды жазу"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Бастау"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Тоқтату"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Жалғастыру үшін &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; қолданбасы құрылғыңыздың микрофонына рұқсат алу керек."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Жалғастыру үшін &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; қолданбасы құрылғыңыздың камерасына рұқсат алу керек."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Құрылғы"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Қолданбалар арасында ауысу үшін жоғары сырғытыңыз"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Қолданбаларды жылдам ауыстырып қосу үшін оңға қарай сүйреңіз"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ашу үшін қайта түртіңіз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ашу үшін жоғары қарай сырғытыңыз."</string>
<string name="keyguard_retry" msgid="886802522584053523">"Әрекетті қайталау үшін жоғары сырғытыңыз."</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC пайдалану үшін құлыпты ашыңыз."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Бұл құрылғы ұйымыңызға тиесілі."</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Бұл құрылғы <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ұйымына тиесілі."</string>
<string name="phone_hint" msgid="6682125338461375925">"Телефонды ашу үшін белгішеден әрі қарай сырғытыңыз"</string>
@@ -825,9 +822,9 @@
<string name="accessibility_long_click_tile" msgid="210472753156768705">"Параметрлерді ашу"</string>
<string name="accessibility_status_bar_headphones" msgid="1304082414912647414">"Құлақаспап қосылды"</string>
<string name="accessibility_status_bar_headset" msgid="2699275863720926104">"Құлақаспап жинағы қосылды"</string>
- <string name="data_saver" msgid="3484013368530820763">"Data Saver"</string>
- <string name="accessibility_data_saver_on" msgid="5394743820189757731">"Дерек сақтағыш қосулы"</string>
- <string name="accessibility_data_saver_off" msgid="58339669022107171">"Дерек сақтағышы өшірулі"</string>
+ <string name="data_saver" msgid="3484013368530820763">"Трафикті үнемдеу"</string>
+ <string name="accessibility_data_saver_on" msgid="5394743820189757731">"Трафикті үнемдеу режимі қосулы"</string>
+ <string name="accessibility_data_saver_off" msgid="58339669022107171">"Трафикті үнемдеу режимі өшірулі"</string>
<string name="switch_bar_on" msgid="1770868129120096114">"Қосулы"</string>
<string name="switch_bar_off" msgid="5669805115416379556">"Өшірулі"</string>
<string name="tile_unavailable" msgid="3095879009136616920">"Қолжетімді емес"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Қолданбаларда <xliff:g id="TYPES_LIST">%s</xliff:g> пайдаланылуда."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" және "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> қолданбасы қазір <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> пайдаланады"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> қолданбасы жақында <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> пайдаланды"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(корпоративтік)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Телефон қоңырауы"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> арқылы)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"геодерек"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index dca2623c9ce2..85557070a51a 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"ការថត​អេក្រង់"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ចាប់ផ្ដើម"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"ឈប់"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"ដើម្បីបន្ត &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ត្រូវការសិទ្ធិចូលប្រើ​មីក្រូហ្វូន​របស់​ឧបករណ៍អ្នក។"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"ដើម្បីបន្ត &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ត្រូវការសិទ្ធិ​ចូលប្រើ​កាមេរ៉ា​របស់ឧបករណ៍អ្នក។"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"ឧបករណ៍"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"អូស​ឡើង​លើ​ដើម្បី​ប្តូរ​កម្មវិធី"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"អូសទៅស្ដាំដើម្បីប្ដូរកម្មវិធីបានរហ័ស"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ប៉ះ​ម្ដង​ទៀត ដើម្បី​បើក"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"អូសឡើងលើ​ដើម្បីបើក"</string>
<string name="keyguard_retry" msgid="886802522584053523">"អូសឡើងលើ ដើម្បី​ព្យាយាម​ម្ដងទៀត"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ដោះសោ ដើម្បីប្រើ NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ឧបករណ៍​នេះគឺជា​កម្មសិទ្ធិរបស់​ស្ថាប័ន​អ្នក"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"ឧបករណ៍នេះ​គឺជា​កម្មសិទ្ធិ​របស់ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"អូសចេញពីរូបតំណាងដើម្បីប្រើទូរស័ព្ទ"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"កម្មវិធី​កំពុងប្រើ <xliff:g id="TYPES_LIST">%s</xliff:g> របស់អ្នក។"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" និង "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> កំពុងប្រើ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> បានប្រើ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ថ្មីៗនេះ"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(សហគ្រាស)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ការហៅទូរសព្ទ"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(តាមរយៈ <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"កាមេរ៉ា"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ទីតាំង"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"មីក្រូហ្វូន"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index e08a29611463..c920cc288bc2 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡ್"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ಪ್ರಾರಂಭಿಸಿ"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"ನಿಲ್ಲಿಸಿ"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"ಮುಂದುವರಿಯಲು, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ಗೆ ನಿಮ್ಮ ಸಾಧನದ ಮೈಕ್ರೋಫೋನ್‌ನ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"ಮುಂದುವರಿಯಲು, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ಗೆ ನಿಮ್ಮ ಸಾಧನದ ಕ್ಯಾಮರಾದ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"ಸಾಧನ"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬದಲಿಸಲು ತ್ವರಿತವಾಗಿ ಬಲಕ್ಕೆ ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ತೆರೆಯಲು ಮತ್ತೆ ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ತೆರೆಯಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ಬಳಸಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ಈ ಸಾಧನವು ನಿಮ್ಮ ಸಂಸ್ಥೆಗೆ ಸೇರಿದೆ"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"ಈ ಸಾಧನವು <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ಗೆ ಸೇರಿದೆ"</string>
<string name="phone_hint" msgid="6682125338461375925">"ಫೋನ್‌ಗಾಗಿ ಐಕಾನ್‌ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%s</xliff:g> ಅನ್ನು ಆ್ಯಪ್‌ಗಳು ಬಳಸುತ್ತಿವೆ."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ಮತ್ತು "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ಅನ್ನು ಬಳಸುತ್ತಿದೆ"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ಇತ್ತೀಚೆಗೆ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ಅನ್ನು ಬಳಸಿದೆ"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ಎಂಟರ್‌ಪ್ರೈಸ್)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ಫೋನ್ ಕರೆ"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> ಮೂಲಕ)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ಕ್ಯಾಮರಾ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ಸ್ಥಳ"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ಮೈಕ್ರೋಫೋನ್‌"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 2b6e2d556864..362c0bc08707 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"화면 녹화"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"시작"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"중지"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"계속하려면 &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;에서 기기 마이크에 액세스해야 합니다."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"계속하려면 &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;에서 기기 카메라에 액세스해야 합니다."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"기기"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"위로 스와이프하여 앱 전환"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"앱을 빠르게 전환하려면 오른쪽으로 드래그"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"다시 탭하여 열기"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"위로 스와이프하여 열기"</string>
<string name="keyguard_retry" msgid="886802522584053523">"위로 스와이프하여 다시 시도해 주세요"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"잠금 해제하여 NFC 사용"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"내 조직에 속한 기기입니다."</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>에 속한 기기입니다."</string>
<string name="phone_hint" msgid="6682125338461375925">"전화 기능을 사용하려면 아이콘에서 스와이프하세요."</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"애플리케이션이 <xliff:g id="TYPES_LIST">%s</xliff:g>을(를) 사용 중입니다."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 및 "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>에서 <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> 사용 중"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>에서 최근에 <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>을(를) 사용함"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(기업용)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"전화 통화"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> 사용)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"카메라"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"위치"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"마이크"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index ffb66f945d63..fe69443c069a 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -418,10 +418,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Экранды жаздыруу"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Баштадык"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Токтотуу"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Улантуу үчүн &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; колдонмосуна түзмөгүңүздүн микрофонун пайдаланууга уруксат беришиңиз керек."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Улантуу үчүн &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; колдонмосуна түзмөгүңүздүн камерасын пайдаланууга уруксат беришиңиз керек."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Түзмөк"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Башка колдонмого которулуу үчүн,, өйдө сүрүңүз"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Колдонмолорду тез которуштуруу үчүн, оңго сүйрөңүз"</string>
@@ -444,8 +442,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ачуу үчүн кайра таптап коюңуз"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ачуу үчүн өйдө сүрүңүз"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Кайталоо үчүн экранды өйдө сүрүңүз"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC технологиясын колдонуу үчүн кулпуcун ачыңыз"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Бул түзмөк уюмуңузга таандык"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Бул түзмөк төмөнкүгө таандык: <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Сүрөтчөнү серпип телефонго өтүңүз"</string>
@@ -972,6 +969,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Колдонмолор төмөнкүлөрдү пайдаланып жатышат: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" жана "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> колдонуп жатат"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Жакында <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> колдонулду"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(корпоративдик)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Телефон чалуу"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> аркылуу)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"жайгашкан жер"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 6e367a123b52..e5e89e44b4df 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"ການບັນທຶກໜ້າຈໍ"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ເລີ່ມ"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"ຢຸດ"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"ເພື່ອດຳເນີນການຕໍ່, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ຕ້ອງການສິດເຂົ້າເຖິງໄມໂຄຣໂຟນອຸປະກອນຂອງທ່ານ."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"ເພື່ອດຳເນີນການຕໍ່, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ຕ້ອງການສິດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງອຸປະກອນທ່ານ."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"ອຸປະກອນ"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ປັດຂື້ນເພື່ອສະຫຼັບແອັບ"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ລາກໄປຂວາເພື່ອສະຫຼັບແອັບດ່ວນ"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ແຕະ​ອີກ​ຄັ້ງ​ເພື່ອ​ເປີດ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ປັດຂຶ້ນເພື່ອເປີດ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ປັດຂຶ້ນເພື່ອລອງໃໝ່"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ປົດລັອກເພື່ອໃຊ້ NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ອຸປະກອນນີ້ເປັນຂອງອົງການທ່ານ"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"ອຸ​ປະ​ກອນ​ນີ້​ເປັນ​ຂອງ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"ປັດ​ຈາກ​ໄອ​ຄອນ​ສຳ​ລັບ​ໂທ​ລະ​ສັບ"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ແອັບພລິເຄຊັນກຳລັງໃຊ້ <xliff:g id="TYPES_LIST">%s</xliff:g> ຂອງທ່ານ."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ແລະ "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ກຳລັງໃຊ້ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ຢູ່"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ໃຊ້ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ເມື່ອບໍ່ດົນມານີ້"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ອົງກອນ)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ໂທລະສັບ"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(ຜ່ານ <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ກ້ອງຖ່າຍຮູບ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ສະຖານທີ່"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ໄມໂຄຣໂຟນ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 34275f4a0228..a5de09533f23 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -420,10 +420,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Ekrano įrašas"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Pradėti"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stabdyti"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Kad būtų galima tęsti, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; reikalinga prieiga prie įrenginio mikrofono."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Kad būtų galima tęsti, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; reikalinga prieiga prie įrenginio fotoaparato."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Įrenginys"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Perbraukite aukštyn, kad perjungtumėte programas"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Vilkite į dešinę, kad greitai perjungtumėte programas"</string>
@@ -446,8 +444,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Palieskite dar kartą, kad atidarytumėte"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Perbraukite aukštyn, kad atidarytumėte"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Jei norite bandyti dar kartą, perbraukite aukštyn"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Norėdami naudoti NFC, atrakinkite"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Šis įrenginys priklauso jūsų organizacijai"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Šis įrenginys priklauso „<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>“"</string>
<string name="phone_hint" msgid="6682125338461375925">"Perbraukite iš telefono piktogramos"</string>
@@ -980,6 +977,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programos naudoja: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ir "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Programa „<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>“ naudoja: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Programa „<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>“ neseniai naudojo: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(įmonės versija)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefono skambutis"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(naud. <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparatą"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"vietovę"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofoną"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 2d427b748b57..019810fe9f84 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -418,10 +418,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Ekrāna ierakstīšana"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Sākt"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Apturēt"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Lai turpinātu, lietotnei &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; nepieciešama piekļuve jūsu ierīces mikrofonam."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Lai turpinātu, lietotnei &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; nepieciešama piekļuve jūsu ierīces kamerai."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Ierīce"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Velciet augšup, lai pārslēgtu lietotnes"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Lai ātri pārslēgtu lietotnes, velciet pa labi"</string>
@@ -444,8 +442,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Pieskarieties vēlreiz, lai atvērtu"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Velciet augšup, lai atvērtu"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Velciet augšup, lai mēģinātu vēlreiz"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Atbloķējiet ierīci, lai izmantotu NFC."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Šī ierīce pieder jūsu organizācijai."</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Šī ierīce pieder organizācijai <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>."</string>
<string name="phone_hint" msgid="6682125338461375925">"Lai lietotu tālruni, velciet no ikonas"</string>
@@ -975,6 +972,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Lietojumprogrammas izmanto šādas funkcijas: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" un "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> pašlaik izmanto šādu darbību: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> nesen izmantoja šādu darbību: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(uzņēmumiem)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Tālruņa zvaniem"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(izmantojot lietotni <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"atrašanās vieta"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofons"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 17d6e10a7d6f..c124eefb52cd 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Снимање екран"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Започни"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Сопри"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"За да продолжи, на &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ѝ е потребен пристап до микрофонот на уредот."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"За да продолжи, на &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ѝ е потребен пристап до камерата на уредот."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Уред"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Повлечете нагоре за да се префрлите од една на друга апликација"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Повлечете надесно за брзо префрлање меѓу апликациите"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Допрете повторно за да се отвори"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Повлечете за да отворите"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Повлечете нагоре за да се обидете повторно"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Отклучете за да користите NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Уредов е во сопственост на организацијата"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Уредов е во сопственост на <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Повлечете од иконата за телефонот"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Апликациите користат <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> користи <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> користеше <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> неодамна"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(претпријатие)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Телефонски повик"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(преку <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"локација"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 916fbe1103bf..965f4df71d7f 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"സ്‌ക്രീൻ റെക്കോർഡ്"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ആരംഭിക്കുക"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"നിര്‍ത്തുക"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"തുടരാൻ, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ആപ്പിന് നിങ്ങളുടെ ഉപകരണത്തിന്റെ മൈക്രോഫോണിലേക്ക് ആക്‌സസ് നൽകേണ്ടതുണ്ട്."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"തുടരാൻ, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ആപ്പിന് നിങ്ങളുടെ ഉപകരണത്തിന്റെ ക്യാമറയിലേക്ക് ആക്‌സസ് നൽകേണ്ടതുണ്ട്."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"ഉപകരണം"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ആപ്പുകൾ മാറാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ആപ്പുകൾ പെട്ടെന്ന് മാറാൻ വലത്തോട്ട് വലിച്ചിടുക"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"തുറക്കുന്നതിന് വീണ്ടും ടാപ്പുചെയ്യുക"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"തുറക്കാൻ മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക"</string>
<string name="keyguard_retry" msgid="886802522584053523">"വീണ്ടും ശ്രമിക്കാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ഉപയോഗിക്കാൻ അൺലോക്ക് ചെയ്യുക"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റേതാണ്"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"ഈ ഉപകരണം <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> എന്ന സ്ഥാപനത്തിന്റേതാണ്"</string>
<string name="phone_hint" msgid="6682125338461375925">"ഫോൺ ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string>
@@ -970,6 +967,16 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ആപ്പുകൾ നിങ്ങളുടെ <xliff:g id="TYPES_LIST">%s</xliff:g> ഉപയോഗിക്കുന്നു."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" കൂടാതെ "</string>
+ <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) -->
+ <skip />
<string name="privacy_type_camera" msgid="7974051382167078332">"ക്യാമറ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ലൊക്കേഷന്‍"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"മൈക്രോഫോൺ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 38bb386f9ca1..400352b6473a 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Дэлгэцийн бичлэг хийх"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Эхлүүлэх"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Зогсоох"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Үргэлжлүүлэхийн тулд &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; таны төхөөрөмжийн микрофонд хандах шаардлагатай."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Үргэлжлүүлэхийн тулд &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; таны төхөөрөмжийн камерт хандах шаардлагатай."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Төхөөрөмж"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Апп сэлгэхийн тулд дээш шударна уу"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Аппуудыг хурдан сэлгэхийн тулд баруун тийш чирнэ үү"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Нээхийн тулд дахин товшино уу"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Нээхийн тулд дээш шударна уу"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Дахин оролдохын тулд дээш шударна уу"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC-г ашиглахын тулд түгжээг тайлна уу"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Энэ төхөөрөмж танай байгууллагад харьяалагддаг"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Энэ төхөөрөмж <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>-д харьяалагддаг"</string>
<string name="phone_hint" msgid="6682125338461375925">"Утсыг гаргахын тулд дүрс тэмдгээс шудрах"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Аппууд таны <xliff:g id="TYPES_LIST">%s</xliff:g>-г ашиглаж байна."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" болон "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>-г ашиглаж байна"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>-г саяхан ашигласан"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(байгууллага)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Утасны дуудлага"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g>-р)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камер"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"байршил"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 1c9cbd2ba6a8..fe1c910c74ed 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -344,10 +344,8 @@
<string name="quick_settings_ime_label" msgid="3351174938144332051">"इनपुट पद्धत"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"स्थान"</string>
<string name="quick_settings_location_off_label" msgid="7923929131443915919">"स्थान बंद"</string>
- <!-- no translation found for quick_settings_camera_label (1367149596242401934) -->
- <skip />
- <!-- no translation found for quick_settings_mic_label (8245831073612564953) -->
- <skip />
+ <string name="quick_settings_camera_label" msgid="1367149596242401934">"कॅमेरा ब्लॉक करा"</string>
+ <string name="quick_settings_mic_label" msgid="8245831073612564953">"मायक्रोफोन म्यूट करा"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"मीडिया डिव्हाइस"</string>
<string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
<string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"फक्त आणीबाणीचे कॉल"</string>
@@ -418,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"स्क्रीन रेकॉर्ड"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"सुरू"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"थांबा"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"पुढे सुरू ठेवण्यासाठी, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ला तुमच्या डिव्हाइसचा मायक्रोफोन अ‍ॅक्सेस करण्याची आवश्यकता आहे."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"पुढे सुरू ठेवण्यासाठी, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ला तुमच्या डिव्हाइसचा कॅमेरा अ‍ॅक्सेस करण्याची आवश्यकता आहे."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"डिव्हाइस"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"अ‍ॅप्स स्विच करण्यासाठी वर स्वाइप करा"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"अ‍ॅप्स वर झटपट स्विच करण्यासाठी उजवीकडे ड्रॅग करा"</string>
@@ -444,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"उघडण्यासाठी पुन्हा टॅप करा"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"उघडण्यासाठी वर स्वाइप करा"</string>
<string name="keyguard_retry" msgid="886802522584053523">"पुन्हा प्रयत्न करण्यासाठी वर स्‍वाइप करा"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC वापरण्यासाठी स्क्रीन अनलॉक करा"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"हे डिव्हाइस तुमच्या संस्थेचे आहे"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"हे डिव्हाइस <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> चे आहे"</string>
<string name="phone_hint" msgid="6682125338461375925">"फोनसाठी चिन्हावरून स्वाइप करा"</string>
@@ -972,6 +967,16 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ॲप्लिकेशन्स तुमचे <xliff:g id="TYPES_LIST">%s</xliff:g> वापरत आहे."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" आणि "</string>
+ <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) -->
+ <skip />
<string name="privacy_type_camera" msgid="7974051382167078332">"कॅमेरा"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"स्थान"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"मायक्रोफोन"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 4751f409c870..b1d0b4748b85 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Rakam Skrin"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Mula"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Berhenti"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Untuk meneruskan proses, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; memerlukan akses kepada mikrofon peranti anda."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Untuk meneruskan proses, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; memerlukan akses kepada kamera peranti anda."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Peranti"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Leret ke atas untuk menukar apl"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Seret ke kanan untuk beralih apl dengan pantas"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ketik lagi untuk membuka"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Leret ke atas untuk buka"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Leret ke atas untuk mencuba lagi"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Buka kunci untuk menggunakan NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Peranti ini milik organisasi anda"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Peranti ini milik <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Leret dari ikon untuk telefon"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikasi sedang menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g> anda."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dan "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> sedang menggunakan <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> menggunakan <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> baru-baru ini"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(perusahaan)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Panggilan telefon"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(melalui <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokasi"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index abd2b2338d59..42b5b230eb6f 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"ဖန်သားပြင် မှတ်တမ်းတင်ရန်"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"စတင်ရန်"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"ရပ်ရန်"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"ဆက်လက်လုပ်ဆောင်ရန် &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; က သင့်စက်၏ မိုက်ခရိုဖုန်းကို အသုံးပြုခွင့်ရရန် လိုအပ်သည်။"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"ဆက်လက်လုပ်ဆောင်ရန် &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; က သင့်စက်၏ ကင်မရာကို အသုံးပြုခွင့်ရရန် လိုအပ်သည်။"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"စက်"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"အက်ပ်များကို ဖွင့်ရန် အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"အက်ပ်များကို ပြောင်းရန် ညာဘက်သို့ ဖိဆွဲပါ"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ဖွင့်ရန် ထပ်ပြီး ပုတ်ပါ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ဖွင့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ထပ်စမ်းကြည့်ရန် အပေါ်သို့ပွတ်ဆွဲပါ"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ကို အသုံးပြုရန် လော့ခ်ဖွင့်ပါ"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ဤစက်ကို သင့်အဖွဲ့အစည်းက ပိုင်ဆိုင်သည်"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"ဤစက်ကို <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> က ပိုင်ဆိုင်သည်"</string>
<string name="phone_hint" msgid="6682125338461375925">"ဖုန်းအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"အပလီကေးရှင်းများက သင်၏ <xliff:g id="TYPES_LIST">%s</xliff:g> ကို အသုံးပြုနေသည်။"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"၊ "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" နှင့် "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> က <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ကို အသုံးပြုနေသည်"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> က <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ကို မကြာသေးမီက အသုံးပြုထားသည်"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(လုပ်ငန်းသုံး)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ဖုန်းခေါ်ဆိုမှု"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> မှတစ်ဆင့်)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ကင်မရာ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"တည်နေရာ"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"မိုက်ခရိုဖုန်း"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index e914399d5f8a..ef48f8fb37c5 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Skjermopptak"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Start"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stopp"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"For å fortsette må &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ha tilgang til enhetsmikrofonen."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"For å fortsette må &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ha tilgang til enhetskameraet."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Enhet"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Sveip opp for å bytte apper"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Dra til høyre for å bytte apper raskt"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Trykk på nytt for å åpne"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Sveip opp for å åpne"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Sveip opp for å prøve igjen"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås opp for å bruke NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Denne enheten tilhører organisasjonen din"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Denne enheten tilhører <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Sveip ikonet for å åpne telefon"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apper bruker <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" og "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> bruker <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> har brukt <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> nylig"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonsamtale"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(til og med <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"posisjon"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index ad087c5e2ceb..2594e8c923dd 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"स्रिनको रेकर्ड"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"सुरु गर्नुहोस्"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"रोक्नुहोस्"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"जारी राख्न &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; लाई तपाईंको यन्त्रको माइक्रोफोन प्रयोग गर्ने अनुमति दिनु पर्ने हुन्छ।"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"जारी राख्न &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; लाई तपाईंको यन्त्रको क्यामेरा प्रयोग गर्ने अनुमति दिनु पर्ने हुन्छ।"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"यन्त्र"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"एपहरू बदल्न माथितिर स्वाइप गर्नुहोस्"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"एपहरू बदल्न द्रुत गतिमा दायाँतिर ड्र्याग गर्नुहोस्"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"खोल्न पुनः ट्याप गर्नुहोस्"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"खोल्न माथितिर स्वाइप गर्नुहोस्"</string>
<string name="keyguard_retry" msgid="886802522584053523">"फेरि प्रयास गर्न माथितिर स्वाइप गर्नुहोस्"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC प्रयोग गर्न स्क्रिन अनलक गर्नुहोस्"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"यो यन्त्र तपाईंको सङ्गठनको स्वामित्वमा छ"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"यो यन्त्र <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> को स्वामित्वमा छ"</string>
<string name="phone_hint" msgid="6682125338461375925">"फोनको लागि आइकनबाट स्वाइप गर्नुहोस्"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"एपहरूले तपाईंको <xliff:g id="TYPES_LIST">%s</xliff:g> प्रयोग गर्दै छन्‌।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" र "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ले <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> प्रयोग गरिरहेको छ"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ले हालसालै <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> प्रयोग गरेको छ"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(इन्टरप्राइज)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"फोन कल"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> मार्फत)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"क्यामेरा"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"स्थान"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"माइक्रोफोन"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 614d37413962..02741322f5ac 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Schermopname"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Starten"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stoppen"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; heeft toegang tot de microfoon van je apparaat nodig om door te gaan."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; heeft toegang tot de camera van je apparaat nodig om door te gaan."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Apparaat"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Swipe omhoog om te schakelen tussen apps"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Sleep naar rechts om snel tussen apps te schakelen"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tik nog eens om te openen"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swipe omhoog om te openen"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swipe omhoog om het opnieuw te proberen"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ontgrendel het apparaat om NFC te gebruiken"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Dit apparaat is eigendom van je organisatie"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Dit apparaat is eigendom van <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Swipen voor telefoon"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Apps gebruiken je <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" en "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> gebruikt de <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> heeft de <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recent gebruikt"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(zakelijke versie)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefoongesprek"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(via <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"locatie"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfoon"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 97af29b38301..16d8a2969e27 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"ସ୍କ୍ରିନ୍ ରେକର୍ଡ"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"ବନ୍ଦ କରନ୍ତୁ"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"ଜାରି ରଖିବାକୁ, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ଆପଣଙ୍କ ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଆକ୍ସେସ୍ ଆବଶ୍ୟକ କରେ।"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"ଜାରି ରଖିବାକୁ, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ଆପଣଙ୍କ ଡିଭାଇସର କ୍ୟାମେରାକୁ ଆକ୍ସେସ୍ ଆବଶ୍ୟକ କରେ।"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"ଡିଭାଇସ୍"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ଆପ୍‌କୁ ବଦଳ କରିବା ପାଇଁ ସ୍ଵାଇପ୍ କରନ୍ତୁ"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ଆପ୍‌ଗୁଡ଼ିକ ମଧ୍ୟରେ ଶୀଘ୍ର ବଦଳ କରିବା ପାଇଁ ଡାହାଣକୁ ଡ୍ରାଗ୍ କରନ୍ତୁ"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ଖୋଲିବା ପାଇଁ ପୁଣି ଟାପ୍‍ କରନ୍ତୁ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ଖୋଲିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ପୁଣି ଚେଷ୍ଟା କରିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ବ୍ୟବହାର କରିବାକୁ ଅନଲକ୍ କରନ୍ତୁ"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ଏହି ଡିଭାଇସଟି ଆପଣଙ୍କ ସଂସ୍ଥାର ଅଟେ"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"ଏହି ଡିଭାଇସଟି <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>ର ଅଟେ"</string>
<string name="phone_hint" msgid="6682125338461375925">"ଫୋନ୍‍ ପାଇଁ ଆଇକନରୁ ସ୍ୱାଇପ୍‍ କରନ୍ତୁ"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ଆପ୍ଲିକେସନ୍‍ଗୁଡିକ ଆପଣଙ୍କ <xliff:g id="TYPES_LIST">%s</xliff:g> ବ୍ୟବହାର କରୁଛନ୍ତି।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ଏବଂ "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ବ୍ୟବହାର କରୁଛି"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ଏବେ <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ବ୍ୟବହାର କରିଛି"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ଏଣ୍ଟରପ୍ରାଇଜ୍)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"ଫୋନକଲ୍"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> ମାଧ୍ୟମରେ)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"କ୍ୟାମେରା"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ଲୋକେସନ୍‍"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ମାଇକ୍ରୋଫୋନ୍"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index e7ffe492c196..d33455d2c82c 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -344,10 +344,8 @@
<string name="quick_settings_ime_label" msgid="3351174938144332051">"ਇਨਪੁੱਟ ਵਿਧੀ"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"ਟਿਕਾਣਾ"</string>
<string name="quick_settings_location_off_label" msgid="7923929131443915919">"ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਬੰਦ"</string>
- <!-- no translation found for quick_settings_camera_label (1367149596242401934) -->
- <skip />
- <!-- no translation found for quick_settings_mic_label (8245831073612564953) -->
- <skip />
+ <string name="quick_settings_camera_label" msgid="1367149596242401934">"ਕੈਮਰਾ ਬਲਾਕ ਕਰੋ"</string>
+ <string name="quick_settings_mic_label" msgid="8245831073612564953">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਮਿਊਟ ਕਰੋ"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"ਮੀਡੀਆ ਡੀਵਾਈਸ"</string>
<string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
<string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"ਸਿਰਫ਼ ਸੰਕਟਕਾਲੀਨ ਕਾਲਾਂ"</string>
@@ -418,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਰ"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ਸ਼ੁਰੂ ਕਰੋ"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"ਰੋਕੋ"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"ਜਾਰੀ ਰੱਖਣ ਲਈ, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"ਜਾਰੀ ਰੱਖਣ ਲਈ, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ਨੂੰ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰਾ ਤੱਕ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"ਡੀਵਾਈਸ"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ਐਪਾਂ ਵਿਚਾਲੇ ਤੇਜ਼ੀ ਨਾਲ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਘਸੀਟੋ"</string>
@@ -444,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਟੈਪ ਕਰੋ"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"ਖੋਲ੍ਹਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="keyguard_retry" msgid="886802522584053523">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਉੱਤੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ਵਰਤਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ਇਹ ਡੀਵਾਈਸ ਤੁਹਾਡੀ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"ਇਹ ਡੀਵਾਈਸ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ"</string>
<string name="phone_hint" msgid="6682125338461375925">"ਫ਼ੋਨ ਲਈ ਪ੍ਰਤੀਕ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
@@ -972,6 +967,16 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ਐਪਲੀਕੇਸ਼ਨਾਂ ਤੁਹਾਡੇ <xliff:g id="TYPES_LIST">%s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀਆਂ ਹਨ।"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ਅਤੇ "</string>
+ <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) -->
+ <skip />
<string name="privacy_type_camera" msgid="7974051382167078332">"ਕੈਮਰਾ"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ਟਿਕਾਣਾ"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 0275626b0a34..6440a65a9eaf 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -420,10 +420,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Nagrywanie ekranu"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Rozpocznij"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zatrzymaj"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Aby kontynuować, musisz przyznać aplikacji „<xliff:g id="APP">%s</xliff:g>” dostęp do mikrofonu urządzenia."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Aby kontynuować, musisz przyznać aplikacji „<xliff:g id="APP">%s</xliff:g>” dostęp do aparatu urządzenia."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Urządzenie"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Przesuń w górę, by przełączyć aplikacje"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Szybko przeciągnij w prawo, by przełączyć aplikacje"</string>
@@ -446,8 +444,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Kliknij ponownie, by otworzyć"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Przesuń w górę, by otworzyć"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Przesuń w górę, by spróbować ponownie"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odblokuj, by użyć NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"To urządzenie należy do Twojej organizacji"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Właściciel tego urządzenia: <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Aby włączyć telefon, przesuń palcem od ikony"</string>
@@ -980,6 +977,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacje używają: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" i "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikacja <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> używa: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikacja <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> używała ostatnio: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(wersja firmowa)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Rozmowa telefoniczna"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(przez: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"aparat"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokalizacja"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index b629b64fc2cf..40dc2de30ac4 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicativos estão usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"O app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está usando <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"O app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> usou <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recentemente"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresarial)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Chamada telefônica"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(pelo app <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"câmera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 43933a4b19f7..22241f8fc280 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"As aplicações estão a utilizar o(a) <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"A app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está a utilizar a app <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Recentemente, a app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> utilizou a app <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresarial)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Chamada telefónica"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(através de <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"câmara"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index b629b64fc2cf..40dc2de30ac4 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -967,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicativos estão usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" e "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"O app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> está usando <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"O app <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> usou <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> recentemente"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(empresarial)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Chamada telefônica"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(pelo app <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"câmera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"localização"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfone"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 5197de3c061c..f32453b9a4d8 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -418,10 +418,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Înregistrarea ecranului"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Începeți"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Opriți"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Pentru a continua, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; necesită acces la microfonul dispozitivului."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Pentru a continua, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; necesită acces la camera dispozitivului."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Dispozitiv"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Glisați în sus pentru a comuta între aplicații"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Glisați la dreapta pentru a comuta rapid între aplicații"</string>
@@ -444,8 +442,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Atingeți din nou pentru a deschide"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Glisați în sus pentru a deschide"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Glisați pentru a încerca din nou"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Deblocați pentru a folosi NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Dispozitivul aparține organizației dvs."</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Acest dispozitiv aparține organizației <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Glisați dinspre telefon"</string>
@@ -975,6 +972,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplicațiile folosesc <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" și "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> folosește <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> a folosit recent <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(prin <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"cameră foto"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"locație"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"microfon"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 17221c9e4170..40fb25865a7c 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -420,10 +420,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Запись экрана"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Начать"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Остановить"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Чтобы продолжить, предоставьте приложению &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ к микрофону устройства."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Чтобы продолжить, предоставьте приложению &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ к камере устройства."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Устройство"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Чтобы переключиться между приложениями, проведите по экрану вверх."</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Перетащите вправо, чтобы быстро переключиться между приложениями"</string>
@@ -446,8 +444,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Нажмите ещё раз, чтобы открыть"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Проведите вверх, чтобы открыть"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Чтобы повторить попытку, проведите вверх"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Чтобы использовать NFC, разблокируйте устройство."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Это устройство принадлежит вашей организации"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Этим устройством владеет организация \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
<string name="phone_hint" msgid="6682125338461375925">"Телефон: проведите от значка"</string>
@@ -980,6 +977,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"В приложениях используется <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Приложение \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\" использует другое (<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>)."</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Приложение \"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>\" недавно использовало другое (<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>)."</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(корпоративная версия)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Приложение для звонков"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(через приложение \"<xliff:g id="ATTRIBUTION">%s</xliff:g>\")"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камера"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"местоположение"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 20bc15050ae2..f3d04091f096 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"තිර පටිගත කිරීම"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ආරම්භ කරන්න"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"නතර කරන්න"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"දිගටම කර ගෙන යාමට, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; හට ඔබගේ උපාංගයෙහි මයික්‍රෆෝනයට ප්‍රවේශය අවශ්‍යයි."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"දිගටම කර ගෙන යාමට, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; හට ඔබගේ උපාංගයෙහි කැමරාවට ප්‍රවේශය අවශ්‍යයි."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"උපාංගය"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"යෙදුම් මාරු කිරීමට ස්වයිප් කරන්න"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ඉක්මනින් යෙදුම් මාරු කිරීමට දකුණට අදින්න"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"විවෘත කිරීමට නැවත තට්ටු කරන්න"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"විවෘත කිරීමට ස්වයිප් කරන්න"</string>
<string name="keyguard_retry" msgid="886802522584053523">"නැවත උත්සාහ කිරීමට ඉහළට ස්වයිප් කරන්න"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC භාවිත කිරීමට අගුලු හරින්න"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"මෙම උපාංගය ඔබේ සංවිධානයට අයිතිය"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"මෙම උපාංගය <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> සංවිධානයට අයිතිය"</string>
<string name="phone_hint" msgid="6682125338461375925">"දුරකථනය සඳහා නිරූපකය වෙතින් ස්වයිප් කරන්න"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"යෙදුම් ඔබේ <xliff:g id="TYPES_LIST">%s</xliff:g> භාවිත කරමින් සිටී."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" සහ "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> භාවිත කරමින් ඇත"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> මෑතකදී <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> භාවිත කළේය"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ව්‍යවසාය)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"දුරකථන ඇමතුම"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> හරහා)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"කැමරාව"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ස්ථානය"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"මයික්‍රෝෆෝනය"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 4984f0f76b9f..7e3f3c010d68 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -420,10 +420,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Záznam obrazovky"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Začať"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Ukončiť"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Ak chcete pokračovať, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; požaduje prístup k mikrofónu zariadenia."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Ak chcete pokračovať, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; požaduje prístup k fotoaparátu zariadenia."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Zariadenie"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Potiahnutím nahor prepnete aplikácie"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Presunutím doprava rýchlo prepnete aplikácie"</string>
@@ -446,8 +444,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Upozornenie otvoríte opätovným klepnutím"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Otvorte potiahnutím prstom nahor"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Potiahnutím nahor to skúste znova"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Ak chcete použiť NFC, odomknite"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Toto zariadenie patrí vašej organizácii"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Toto zariadení patrí organizácii <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telefón otvoríte prejdením prstom od ikony"</string>
@@ -980,6 +977,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikácie používajú zoznam <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" a "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> používa aplikáciu <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikácia <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> použila nedávno aplikáciu <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(podniková verzia)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonický hovor"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(prostredníctvom aplikácie <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparát"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"poloha"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofón"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index ffc6c6683b9d..b7ebea9ebb19 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -420,10 +420,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Snemanje zaslona"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Začni"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Ustavi"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Za nadaljevanje potrebuje aplikacija &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; dostop do mikrofona v napravi."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Za nadaljevanje potrebuje aplikacija &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; dostop do fotoaparata v napravi."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Naprava"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Za preklop aplikacij povlecite navzgor"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Povlecite v desno za hiter preklop med aplikacijami"</string>
@@ -446,8 +444,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Znova se dotaknite, da odprete"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Povlecite navzgor, da odprete"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Povlecite navzgor za vnovičen poskus"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Odklenite napravo, če želite uporabljati vmesnik NFC."</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Ta naprava pripada vaši organizaciji"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Ta naprava pripada organizaciji <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Povlecite z ikone za telefon"</string>
@@ -980,6 +977,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacije uporabljajo <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" in "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> uporablja: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Aplikacija <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> je nedavno uporabila: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(za podjetja)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonski klici"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(prek aplikacije <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokacijo"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 21ac1e05a073..fede55cd86d8 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Regjistrimi i ekranit"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Nis"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Ndalo"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Për të vazhduar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ka nevojë të qaset në mikrofonin e pajisjes sate."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Për të vazhduar, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ka nevojë të qaset në kamerën e pajisjes sate."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Pajisja"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Rrëshqit shpejt lart për të ndërruar aplikacionet"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Zvarrit djathtas për të ndërruar aplikacionet me shpejtësi"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Trokit përsëri për ta hapur"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Rrëshqit lart për ta hapur"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Rrëshqit lart për të provuar përsëri"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Shkyçe për të përdorur NFC-në"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Kjo pajisje i përket organizatës sate"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Kjo pajisje i përket <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Rrëshqit për të hapur telefonin"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Aplikacionet po përdorin <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" dhe "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> po përdor <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ka përdorur <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> së fundi"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ndërmarrje)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Phonecall"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(nëpërmjet <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamerën"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"vendndodhjen"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofonin"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index e154cc5e3931..0d822464611a 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -418,10 +418,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Снимак екрана"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Почните"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Зауставите"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; захтева приступ микрофону уређаја ради настављања."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; захтева приступ камери уређаја ради настављања."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Уређај"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Превуците нагоре да бисте мењали апликације"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Превуците удесно да бисте брзо променили апликације"</string>
@@ -444,8 +442,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Додирните поново да бисте отворили"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Превуците нагоре да бисте отворили"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Превуците нагоре да бисте пробали поново"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Откључајте да бисте користили NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Овај уређај припада организацији"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Овај уређај припада организацији <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Превуците од иконе за телефон"</string>
@@ -975,6 +972,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Апликације користе <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" и "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Апликација <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> користи: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Апликација <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> је недавно користила: <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(за предузећа)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Телефонски позив"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(преко: <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камеру"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"локацију"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"микрофон"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 66ae2276fc8f..969bdcd7eb17 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Skärminspelning"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Starta"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stoppa"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; behöver behörighet till enhetens mikrofon för att fortsätta."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; behöver behörighet till enhetens kamera för att fortsätta."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Enhet"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Byt appar genom att svepa uppåt"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Tryck och dra åt höger för att snabbt byta mellan appar"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Tryck igen för att öppna"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Öppna genom att svepa uppåt"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Svep uppåt om du vill försöka igen"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Lås upp om du vill använda NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Den här enheten tillhör organisationen"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Den här enheten tillhör <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Svep från ikonen och öppna telefonen"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"<xliff:g id="TYPES_LIST">%s</xliff:g> används av appar."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" och "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> använder <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> använde <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> nyligen"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(företag)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefonsamtal"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(genom <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"plats"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 26e6b8c94a52..4055e8da981d 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Rekodi ya Skrini"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Anza kurekodi"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Acha kurekodi"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Ili uendelee, &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; inahitaji ruhusa ya kufikia maikrofoni ya kifaa chako."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Ili uendelee, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; inahitaji ruhusa ya kufikia kamera ya kifaa chako."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Kifaa"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Telezesha kidole juu ili ubadilishe programu"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Buruta kulia ili ubadilishe programu haraka"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Gusa tena ili ufungue"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Telezesha kidole juu ili ufungue"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Telezesha kidole juu ili ujaribu tena"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Fungua ili utumie NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Kifaa hiki kinamilikiwa na shirika lako"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Kifaa hiki kinamilikiwa na <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telezesha kidole kutoka kwa aikoni ili ufikie simu"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Programu zinatumia <xliff:g id="TYPES_LIST">%s</xliff:g> yako."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" na "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> inatumia <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ilitumia <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> hivi majuzi"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(biashara)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Simu"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(kupitia <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"mahali"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"maikrofoni"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 132713bc1931..cbac87e6390a 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"ஸ்கிரீன் ரெக்கார்டு"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"தொடங்கு"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"நிறுத்து"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"தொடர, உங்கள் சாதனத்தின் மைக்ரோஃபோனை அணுகுவதற்கு &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ஆப்ஸுக்கு அனுமதி வேண்டும்."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"தொடர, உங்கள் சாதனத்தின் கேமராவை அணுகுவதற்கு &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ஆப்ஸுக்கு அனுமதி வேண்டும்."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"சாதனம்"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ஆப்ஸிற்கு இடையே மாற்றுவதற்கு, மேல்நோக்கி ஸ்வைப் செய்க"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ஆப்ஸை வேகமாக மாற்ற, வலப்புறம் இழுக்கவும்"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"திறக்க, மீண்டும் தட்டவும்"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"திறப்பதற்கு மேல் நோக்கி ஸ்வைப் செய்யவும்"</string>
<string name="keyguard_retry" msgid="886802522584053523">"மீண்டும் முயல மேல்நோக்கி ஸ்வைப் செய்யவும்"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCயைப் பயன்படுத்த அன்லாக் செய்யவும்"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு சொந்தமானது"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"இந்த சாதனம் <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> நிறுவனத்துக்கு சொந்தமானது"</string>
<string name="phone_hint" msgid="6682125338461375925">"ஃபோனிற்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"உங்கள் <xliff:g id="TYPES_LIST">%s</xliff:g> ஆகியவற்றை ஆப்ஸ் பயன்படுத்துகின்றன."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" மற்றும் "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ஆப்ஸ் <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> பயன்படுத்துகிறது"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"சமீபத்தில் <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ஆப்ஸ் <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> பயன்படுத்தியுள்ளது"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(நிறுவனப் பதிப்பு)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"மொபைல் அழைப்பு"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> மூலம்)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"கேமரா"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"இருப்பிடம்"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"மைக்ரோஃபோன்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 13758d9be98f..45ef33900ccd 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"స్క్రీన్ రికార్డ్"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"ప్రారంభించు"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"ఆపు"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"కొనసాగించడానికి, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;కు మీ పరికరం యొక్క మైక్రోఫోన్ యాక్సెస్ అవసరం."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"కొనసాగించడానికి, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&amp;gtకు మీ పరికరం యొక్క కెమెరా యాక్సెస్ అవసరం."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"పరికరం"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"యాప్‌లను మార్చడం కోసం ఎగువకు స్వైప్ చేయండి"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"యాప్‌లను శీఘ్రంగా స్విచ్ చేయడానికి కుడి వైపుకు లాగండి"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"తెరవడానికి మళ్లీ నొక్కండి"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"తెరవడానికి, పైకి స్వైప్ చేయండి"</string>
<string name="keyguard_retry" msgid="886802522584053523">"మళ్ళీ ప్రయత్నించడానికి పైకి స్వైప్ చేయండి"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFCను ఉపయోగించడానికి అన్‌లాక్ చేయండి"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"ఈ పరికరం మీ సంస్థకు చెందినది"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"ఈ పరికరం <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>కు చెందినది"</string>
<string name="phone_hint" msgid="6682125338461375925">"ఫోన్ కోసం చిహ్నాన్ని స్వైప్ చేయండి"</string>
@@ -970,6 +967,16 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"అప్లికేషన్‌లు మీ <xliff:g id="TYPES_LIST">%s</xliff:g>ని ఉపయోగిస్తున్నాయి."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" మరియు "</string>
+ <!-- no translation found for ongoing_privacy_dialog_using_op (4125175620929701569) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_recent_op (4255923947334262404) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_enterprise (4082735415905550729) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_phonecall (3526223335298089311) -->
+ <skip />
+ <!-- no translation found for ongoing_privacy_dialog_attribution_text (9186683306719924646) -->
+ <skip />
<string name="privacy_type_camera" msgid="7974051382167078332">"కెమెరా"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"లొకేషన్"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"మైక్రోఫోన్"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 5c082931ea2b..8b197acb1958 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"บันทึกหน้าจอ"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"เริ่ม"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"หยุด"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ต้องได้รับสิทธิ์เข้าถึงไมโครโฟนของอุปกรณ์เพื่อดำเนินการต่อ"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ต้องได้รับสิทธิ์เข้าถึงกล้องของอุปกรณ์เพื่อดำเนินการต่อ"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"อุปกรณ์"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"เลื่อนขึ้นเพื่อสลับแอป"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"ลากไปทางขวาเพื่อสลับแอปอย่างรวดเร็ว"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"แตะอีกครั้งเพื่อเปิด"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"เลื่อนขึ้นเพื่อเปิด"</string>
<string name="keyguard_retry" msgid="886802522584053523">"เลื่อนขึ้นเพื่อลองอีกครั้ง"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"ปลดล็อกเพื่อใช้ NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g> เป็นเจ้าของอุปกรณ์นี้"</string>
<string name="phone_hint" msgid="6682125338461375925">"เลื่อนไอคอนโทรศัพท์"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"หลายแอปพลิเคชันใช้<xliff:g id="TYPES_LIST">%s</xliff:g>ของคุณอยู่"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" และ "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> กำลังใช้<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ใช้<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>เมื่อเร็วๆ นี้"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(องค์กร)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"โทรศัพท์"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(ผ่านทาง <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"กล้องถ่ายรูป"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"ตำแหน่ง"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"ไมโครโฟน"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 9f322325af5f..a4a768bdc959 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Pag-record ng Screen"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Magsimula"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Ihinto"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Para magpatuloy, kailangan ng &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ng access sa mikropono ng iyong device."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Para magpatuloy, kailangan ng &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ng access sa camera ng iyong device."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Device"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Mag-swipe pataas upang lumipat ng app"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"I-drag pakanan para mabilisang magpalipat-lipat ng app"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"I-tap ulit upang buksan"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Mag-swipe pataas para buksan"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Mag-swipe pataas para subukan ulit"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"I-unlock para magamit ang NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Pagmamay-ari ng iyong organisasyon ang device na ito"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Pagmamay-ari ng <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> ang device na ito"</string>
<string name="phone_hint" msgid="6682125338461375925">"Mag-swipe mula sa icon para sa telepono"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Ginagamit ng mga application ang iyong <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" at "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Ginagamit ng <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ang <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Kamakailang ginamit ng <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> ang <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(enterprise)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Tawag sa telepono"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(sa pamamagitan ng <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"camera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"lokasyon"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikropono"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 8c1016d631fa..3040ea0a2c3d 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Ekran Kaydı"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Başlat"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Durdur"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Devam etmek için &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; uygulamasının cihazınızın mikrofonuna erişmesi gerekiyor."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Devam etmek için &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; uygulamasının cihazınızın kamerasına erişmesi gerekiyor."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Cihaz"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Uygulamalar arasında geçiş yapmak için yukarı kaydırın"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Uygulamaları hızlıca değiştirmek için sağa kaydırın"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Açmak için tekrar dokunun"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Açmak için yukarı kaydırın"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Tekrar denemek için yukarı kaydırın"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC\'yi kullanmak için kilidi açın"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Bu cihaz, kuruluşunuza ait"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Bu cihaz <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> adlı kuruluşa ait"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telefon için, simgeden hızlıca kaydırın"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Uygulamalar şunları kullanıyor: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" ve "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> uygulamasını kullanıyor"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>, yakın zamanda <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> uygulamasını kullandı"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(kurumsal)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefon çağrısı"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> aracılığıyla)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"konum"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 45d4ad98d411..b6b7cee5c4f9 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -420,10 +420,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Запис екрана"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Почати"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Зупинити"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Щоб продовжити, надайте додатку &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ до мікрофона пристрою."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Щоб продовжити, надайте додатку &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; доступ до камери пристрою."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Пристрій"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Проводьте пальцем угору, щоб переходити між додатками"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Перетягуйте праворуч, щоб швидко переходити між додатками"</string>
@@ -446,8 +444,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Торкніться знову, щоб відкрити"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Проведіть пальцем угору, щоб відкрити"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Проведіть пальцем угору, щоб повторити спробу"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Розблокуйте екран, щоб скористатись NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Цей пристрій належить вашій організації"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Цей пристрій належить організації \"<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>\""</string>
<string name="phone_hint" msgid="6682125338461375925">"Телефон: проведіть пальцем від значка"</string>
@@ -980,6 +977,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Додатки використовують <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" і "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"Додаток <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> використовує функцію \"<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>\""</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Додаток <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> нещодавно використав функцію \"<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>\""</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(корпоративний додаток)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Додаток для телефонних дзвінків"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(через <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"камеру"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"місце"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"мікрофон"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 021679724d4e..15c9607aa78f 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"اسکرین ریکارڈر کریں"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"آغاز"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"روکیں"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"‏جاری رکھنے کیلئے ‎&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;‎ کو آپ کے آلے کے مائیکروفون تک رسائی درکار ہے۔"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"‏جاری رکھنے کیلئے ‎&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;‎ کو آپ کے آلے کے کیمرے تک رسائی درکار ہے۔"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"آلہ"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"ایپس سوئچ کرنے کیلئے اوپر سوائپ کریں"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"تیزی سے ایپس کو سوئچ کرنے کے لیے دائیں طرف گھسیٹیں"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"کھولنے کیلئے دوبارہ تھپتھپائیں"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"کھولنے کے لیے اوپر سوائپ کريں"</string>
<string name="keyguard_retry" msgid="886802522584053523">"دوبارہ کوشش کرنے کے لیے اوپر سوائپ کريں"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"‏NFC استعمال کرنے کیلئے غیر مقفل کریں"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"یہ آلہ آپ کی تنظیم کا ہے"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"یہ آلہ <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> کا ہے"</string>
<string name="phone_hint" msgid="6682125338461375925">"فون کیلئے آئیکن سے سوائپ کریں"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"ایپلیکیشنز آپ کی <xliff:g id="TYPES_LIST">%s</xliff:g> کا استعمال کر رہی ہیں۔"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"، "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" اور "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> کا استعمال کر رہی ہے"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> نے حال ہی میں <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> کا استعمال کیا"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(انٹرپرائز)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"فون کال"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> کے ذریعے)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"کیمرا"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"مقام"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"مائیکروفون"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index e9bc22ac48c6..3044a98ad814 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -345,7 +345,7 @@
<string name="quick_settings_location_label" msgid="2621868789013389163">"Joylashuv"</string>
<string name="quick_settings_location_off_label" msgid="7923929131443915919">"Joylashuvni aniqlash xizmati yoqilmagan"</string>
<string name="quick_settings_camera_label" msgid="1367149596242401934">"Kamerani bloklash"</string>
- <string name="quick_settings_mic_label" msgid="8245831073612564953">"Mikrofonni oʻchirish"</string>
+ <string name="quick_settings_mic_label" msgid="8245831073612564953">"Mikrofonni ovozsiz qilish"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"Media qurilma"</string>
<string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
<string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"Favqulodda chaqiruvlar"</string>
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Ekranni yozib olish"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Boshlash"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Toʻxtatish"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Davom etish uchun &lt;b&gt; <xliff:g id="APP">%s</xliff:g>&lt;/b&gt; mikrofoningizdan foydalanishi kerak."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Davom etish uchun &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; qurilmangiz kamerasiga kirishi kerak."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Qurilma"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Ilovalarni almashtirish uchun ekranni tepaga suring"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Ilovalarni tezkor almashtirish uchun o‘ngga torting"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Ochish uchun yana bosing"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Ochish uchun tepaga suring"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Qayta urinish uchun tepaga suring"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"NFC ishlatish uchun qurilma qulfini oching"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Bu qurilma tashkilotingizga tegishli"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Bu qurilma <xliff:g id="ORGANIZATION_NAME">%s</xliff:g> tashkilotiga tegishli"</string>
<string name="phone_hint" msgid="6682125338461375925">"Telefonni ochish uchun suring"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Ilovalarda ishlatilmoqda: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" va "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> hozir <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ishlatmoqda"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> yaqinda <xliff:g id="APP_OPP_NAME">%2$s</xliff:g> ishlatgan"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(korporativ)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Telefon chaqiruvi"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(<xliff:g id="ATTRIBUTION">%s</xliff:g> orqali)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"joylashuv"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index e62a33bc8bc9..4913be4f9565 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Ghi lại nội dung trên màn hình"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Bắt đầu"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Dừng"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Để tiếp tục, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; cần quyền truy cập vào micrô trên thiết bị của bạn."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Để tiếp tục, &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; cần quyền truy cập vào máy ảnh trên thiết bị của bạn."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Thiết bị"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Vuốt lên để chuyển đổi ứng dụng"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Kéo sang phải để chuyển đổi nhanh giữa các ứng dụng"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Nhấn lại để mở"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Vuốt lên để mở"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Vuốt lên để thử lại"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Mở khóa để sử dụng NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Thiết bị này thuộc về tổ chức của bạn"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Thiết bị này thuộc về <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Vuốt từ biểu tượng để mở điện thoại"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Các ứng dụng đang dùng <xliff:g id="TYPES_LIST">%s</xliff:g> của bạn."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" và "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> đang sử dụng <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"Gần đây, <xliff:g id="APPLICATION_NAME">%1$s</xliff:g> đã sử dụng <xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(doanh nghiệp)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Gọi điện thoại"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(thông qua <xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"máy ảnh"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"vị trí"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"micrô"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 050eea515f74..3479d009804c 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"屏幕录制"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"开始"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"停止"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"如要继续操作,请向&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;授予设备的麦克风使用权。"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"如要继续操作,请向&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt;授予设备的相机使用权。"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"设备"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"向上滑动可切换应用"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"向右拖动可快速切换应用"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"再次点按即可打开"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑动即可打开"</string>
<string name="keyguard_retry" msgid="886802522584053523">"向上滑动即可重试"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"需要解锁才能使用 NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"此设备归贵单位所有"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"此设备归<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>所有"</string>
<string name="phone_hint" msgid="6682125338461375925">"滑动图标即可拨打电话"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多个应用正在使用您的<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>正在使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>最近曾使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(企业版)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"电话"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(通过<xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"相机"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"位置信息"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"麦克风"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 15709f78a8e0..314b728071af 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"畫面錄影"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"開始"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"停"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"如要繼續,&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; 需要裝置的麥克風存取權。"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"如要繼續,&lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; 需要裝置的相機存取權。"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"裝置"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"向上滑動即可切換應用程式"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"向右拖曳即可快速切換應用程式"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"再次輕按即可開啟"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
<string name="keyguard_retry" msgid="886802522584053523">"請向上滑動以再試一次"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"解鎖以使用 NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"此裝置屬於您的機構"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"此裝置屬於「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」"</string>
<string name="phone_hint" msgid="6682125338461375925">"從圖示滑動即可使用手機功能"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多個應用程式正在使用<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"「<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>」正在使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"「<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>」最近曾使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(企業版本)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"電話"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(透過「<xliff:g id="ATTRIBUTION">%s</xliff:g>」)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"相機"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"位置"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"麥克風"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 90cf0b16387b..68b631fff5da 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"螢幕畫面錄製"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"開始"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"停止"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"如要繼續操作,請將裝置的麥克風存取權授予「<xliff:g id="APP">%s</xliff:g>」&lt;b&gt;&lt;/b&gt;。"</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"如要繼續操作,請將裝置的相機存取權授予「<xliff:g id="APP">%s</xliff:g>」&lt;b&gt;&lt;/b&gt;。"</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"裝置"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"向上滑動即可切換應用程式"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"向右拖曳即可快速切換應用程式"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"再次輕觸即可開啟"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"向上滑動即可開啟"</string>
<string name="keyguard_retry" msgid="886802522584053523">"向上滑動即可重試"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"如要使用 NFC,請先解鎖"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"這部裝置的擁有者為貴機構"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"這部裝置的擁有者為「<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>」"</string>
<string name="phone_hint" msgid="6682125338461375925">"滑動手機圖示即可啟用"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"有多個應用程式正在使用<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">"、 "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" 和 "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"「<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>」正在使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"「<xliff:g id="APPLICATION_NAME">%1$s</xliff:g>」最近曾使用<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(企業版)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"電話"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(透過「<xliff:g id="ATTRIBUTION">%s</xliff:g>」)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"相機"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"位置"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"麥克風"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 3a77730a9421..78c4f17edf2d 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -416,10 +416,8 @@
<string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Irekhodi lesikrini"</string>
<string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Qala"</string>
<string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Misa"</string>
- <!-- no translation found for sensor_privacy_start_use_mic_dialog_content (8643239110815357707) -->
- <skip />
- <!-- no translation found for sensor_privacy_start_use_camera_dialog_content (7773612142162829116) -->
- <skip />
+ <string name="sensor_privacy_start_use_mic_dialog_content" msgid="8643239110815357707">"Ukuze uqhubeke, &lt;b&gt;i-<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; idinga ukufinyelela imakrofoni yedivayisi yakho."</string>
+ <string name="sensor_privacy_start_use_camera_dialog_content" msgid="7773612142162829116">"Ukuze uqhubeke, &lt;b&gt;i-<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; idinga ukufinyelela ikhamera yakho."</string>
<string name="media_seamless_remote_device" msgid="177033467332920464">"Idivayisi"</string>
<string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Swayiphela phezulu ukuze ushintshe izinhlelo zokusebenza"</string>
<string name="recents_quick_scrub_onboarding" msgid="765934300283514912">"Hudula ngqo ukuze ushintshe ngokushesha izinhlelo zokusebenza"</string>
@@ -442,8 +440,7 @@
<string name="notification_tap_again" msgid="4477318164947497249">"Thepha futhi ukuze uvule"</string>
<string name="keyguard_unlock" msgid="8031975796351361601">"Swayiphela phezulu ukuze uvule"</string>
<string name="keyguard_retry" msgid="886802522584053523">"Swayiphela phezulu ukuze uzame futhi"</string>
- <!-- no translation found for require_unlock_for_nfc (1305686454823018831) -->
- <skip />
+ <string name="require_unlock_for_nfc" msgid="1305686454823018831">"Vula ukuze usebenzise i-NFC"</string>
<string name="do_disclosure_generic" msgid="4896482821974707167">"Le divayisi eyenhlangano yakho"</string>
<string name="do_disclosure_with_name" msgid="2091641464065004091">"Le divayisi ngeye-<xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
<string name="phone_hint" msgid="6682125338461375925">"Swayiphela ifoni kusukela kusithonjana"</string>
@@ -970,6 +967,11 @@
<string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Izinhlelo zokusebenza zisebenzisa i-<xliff:g id="TYPES_LIST">%s</xliff:g> yakho."</string>
<string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
<string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" kanye "</string>
+ <string name="ongoing_privacy_dialog_using_op" msgid="4125175620929701569">"I-<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> isebenzisa i-<xliff:g id="APP_OPP_NAME">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_recent_op" msgid="4255923947334262404">"I-<xliff:g id="APPLICATION_NAME">%1$s</xliff:g> isebenzise i-<xliff:g id="APP_OPP_NAME">%2$s</xliff:g> kamuva nje"</string>
+ <string name="ongoing_privacy_dialog_enterprise" msgid="4082735415905550729">"(ibhizinisi)"</string>
+ <string name="ongoing_privacy_dialog_phonecall" msgid="3526223335298089311">"Ikholi yefoni"</string>
+ <string name="ongoing_privacy_dialog_attribution_text" msgid="9186683306719924646">"(kuya ku-<xliff:g id="ATTRIBUTION">%s</xliff:g>)"</string>
<string name="privacy_type_camera" msgid="7974051382167078332">"ikhamera"</string>
<string name="privacy_type_location" msgid="7991481648444066703">"indawo"</string>
<string name="privacy_type_microphone" msgid="9136763906797732428">"imakrofoni"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e5109307c4f4..1fac96bb181d 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1181,6 +1181,12 @@
<dimen name="ongoing_appops_dialog_side_margins">@dimen/notification_shade_content_margin_horizontal</dimen>
+ <dimen name="ongoing_appops_dialog_circle_size">32dp</dimen>
+
+ <dimen name="ongoing_appops_dialog_icon_size">20dp</dimen>
+
+ <dimen name="ongoing_appops_dialog_side_padding">16dp</dimen>
+
<!-- Size of the RAT type for CellularTile -->
<dimen name="celltile_rat_type_size">10sp</dimen>
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index 49f91096543a..01e54ff60582 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -31,4 +31,9 @@
<!-- AOD/Lockscreen alternate layout -->
<bool name="flag_keyguard_layout">false</bool>
+
+ <bool name="flag_brightness_slider">false</bool>
+
+ <!-- People Tile flag -->
+ <bool name="flag_conversations">false</bool>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 4baa06a393a8..cb7327f7629c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2556,8 +2556,8 @@
<!-- Text for privacy dialog, indicating that the application is the enterprise version [CHAR LIMIT=NONE] -->
<string name="ongoing_privacy_dialog_enterprise">(enterprise)</string>
- <!-- Text for privacy dialog, identifying the phonecall app [CHAR LIMIT=NONE]-->
- <string name="ongoing_privacy_dialog_phonecall">Phonecall</string>
+ <!-- Text for privacy dialog, identifying the phone call app [CHAR LIMIT=NONE]-->
+ <string name="ongoing_privacy_dialog_phonecall">Phone call</string>
<!-- Text for privacy dialog, indicating that an app is using an op on behalf of another [CHAR LIMIT=NONE] -->
<string name="ongoing_privacy_dialog_attribution_text">(through <xliff:g id="attribution" example="Special app">%s</xliff:g>)</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index db260ce1b7b4..ad4e78e8e507 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -745,4 +745,9 @@
* Title: headline, medium 20sp
* Message: body, 16 sp -->
<style name="Theme.ControlsRequestDialog" parent="@*android:style/Theme.DeviceDefault.Dialog.Alert"/>
+
+ <style name="TextAppearance.PrivacyDialog">
+ <item name="android:textSize">14sp</item>
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+ </style>
</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
index 2a0715ed764c..87f6b8202ded 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
@@ -118,9 +118,9 @@ public class RemoteAnimationTargetCompat {
}
public static RemoteAnimationTargetCompat[] wrap(RemoteAnimationTarget[] apps) {
- final RemoteAnimationTargetCompat[] appsCompat =
- new RemoteAnimationTargetCompat[apps != null ? apps.length : 0];
- for (int i = 0; i < apps.length; i++) {
+ final int length = apps != null ? apps.length : 0;
+ final RemoteAnimationTargetCompat[] appsCompat = new RemoteAnimationTargetCompat[length];
+ for (int i = 0; i < length; i++) {
appsCompat[i] = new RemoteAnimationTargetCompat(apps[i]);
}
return appsCompat;
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
index 62d30935dd5c..ca99563986b4 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.java
@@ -38,7 +38,7 @@ import kotlin.Unit;
* The time's text color is a gradient that changes its colors based on its controller.
*/
public class AnimatableClockView extends TextView {
- private static final CharSequence FORMAT_12_HOUR = "h\nmm";
+ private static final CharSequence FORMAT_12_HOUR = "hh\nmm";
private static final CharSequence FORMAT_24_HOUR = "HH\nmm";
private static final long ANIM_DURATION = 300;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 9908e672535f..d9a1eb6c0b28 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1909,12 +1909,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
/**
- * Whether to show the lock icon on lock screen and bouncer. This depends on the enrolled
- * biometrics to the device.
+ * Whether to show the lock icon on lock screen and bouncer.
*/
- public boolean shouldShowLockIcon() {
- return isFaceAuthEnabledForUser(KeyguardUpdateMonitor.getCurrentUser())
- && !isUdfpsEnrolled();
+ public boolean canShowLockIcon() {
+ if (mLockScreenMode == LOCK_SCREEN_MODE_LAYOUT_1) {
+ return isFaceAuthEnabledForUser(KeyguardUpdateMonitor.getCurrentUser())
+ && !isUdfpsEnrolled();
+ }
+ return true;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 036fcf3bec27..78f7966558ab 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -127,7 +127,7 @@ public class SystemUIApplication extends Application implements
}
// If SHOW_PEOPLE_SPACE is true, enable People Space widget provider.
- // TODO(b/170396074): Remove this when we don't need a widget anymore.
+ // TODO(b/170396074): Migrate to new feature flag (go/silk-flags-howto)
try {
int showPeopleSpace = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.SHOW_PEOPLE_SPACE, 1);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index b373cff489f6..008e8f506e0f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -22,29 +22,22 @@ import static com.android.internal.util.Preconditions.checkNotNull;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.RectF;
-import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IUdfpsOverlayController;
-import android.os.PowerManager;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.TextUtils;
import android.util.Log;
-import android.util.MathUtils;
-import android.util.Spline;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
+import android.view.Surface;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.internal.BrightnessSynchronizer;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
@@ -53,10 +46,6 @@ import com.android.systemui.doze.DozeReceiver;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.util.concurrency.DelayableExecutor;
-import com.android.systemui.util.settings.SystemSettings;
-
-import java.io.FileWriter;
-import java.io.IOException;
import javax.inject.Inject;
@@ -73,16 +62,13 @@ import javax.inject.Inject;
*/
@SuppressWarnings("deprecation")
@SysUISingleton
-public class UdfpsController implements DozeReceiver {
+public class UdfpsController implements UdfpsView.HbmCallback, DozeReceiver {
private static final String TAG = "UdfpsController";
- // Gamma approximation for the sRGB color space.
- private static final float DISPLAY_GAMMA = 2.2f;
private static final long AOD_INTERRUPT_TIMEOUT_MILLIS = 1000;
private final Context mContext;
private final FingerprintManager mFingerprintManager;
private final WindowManager mWindowManager;
- private final SystemSettings mSystemSettings;
private final DelayableExecutor mFgExecutor;
private final StatusBarStateController mStatusBarStateController;
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
@@ -90,23 +76,6 @@ public class UdfpsController implements DozeReceiver {
@VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps;
private final WindowManager.LayoutParams mCoreLayoutParams;
private final UdfpsView mView;
- // Debugfs path to control the high-brightness mode.
- private final String mHbmPath;
- private final String mHbmEnableCommand;
- private final String mHbmDisableCommand;
- private final boolean mHbmSupported;
- // Brightness in nits in the high-brightness mode.
- private final float mMaxNits;
- // A spline mapping from the device's backlight value, normalized to the range [0, 1.0], to a
- // brightness in nits.
- private final Spline mBacklightToNitsSpline;
- // A spline mapping from a value in nits to a backlight value of a hypothetical panel whose
- // maximum backlight value corresponds to our panel's high-brightness mode.
- // The output is normalized to the range [0, 1.0].
- private Spline mNitsToHbmBacklightSpline;
- // Default non-HBM backlight value normalized to the range [0, 1.0]. Used as a fallback when the
- // actual brightness value cannot be retrieved.
- private final float mDefaultBrightness;
// Indicates whether the overlay is currently showing. Even if it has been requested, it might
// not be showing.
private boolean mIsOverlayShowing;
@@ -152,7 +121,7 @@ public class UdfpsController implements DozeReceiver {
@SuppressLint("ClickableViewAccessibility")
private final UdfpsView.OnTouchListener mOnTouchListener = (v, event) -> {
UdfpsView view = (UdfpsView) v;
- final boolean isFingerDown = view.isShowScrimAndDot();
+ final boolean isFingerDown = view.isIlluminationRequested();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
@@ -183,9 +152,7 @@ public class UdfpsController implements DozeReceiver {
@Main Resources resources,
LayoutInflater inflater,
@Nullable FingerprintManager fingerprintManager,
- DisplayManager displayManager,
WindowManager windowManager,
- SystemSettings systemSettings,
@NonNull StatusBarStateController statusBarStateController,
@Main DelayableExecutor fgExecutor,
@NonNull ScrimController scrimController) {
@@ -194,7 +161,6 @@ public class UdfpsController implements DozeReceiver {
// fingerprint manager should never be null.
mFingerprintManager = checkNotNull(fingerprintManager);
mWindowManager = windowManager;
- mSystemSettings = systemSettings;
mFgExecutor = fgExecutor;
mStatusBarStateController = statusBarStateController;
@@ -211,72 +177,18 @@ public class UdfpsController implements DozeReceiver {
PixelFormat.TRANSLUCENT);
mCoreLayoutParams.setTitle(TAG);
mCoreLayoutParams.setFitInsetsTypes(0);
+ mCoreLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
mCoreLayoutParams.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
mCoreLayoutParams.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
mView = (UdfpsView) inflater.inflate(R.layout.udfps_view, null, false);
mView.setSensorProperties(mSensorProps);
+ mView.setHbmCallback(this);
- mHbmPath = resources.getString(R.string.udfps_hbm_sysfs_path);
- mHbmEnableCommand = resources.getString(R.string.udfps_hbm_enable_command);
- mHbmDisableCommand = resources.getString(R.string.udfps_hbm_disable_command);
-
- mHbmSupported = !TextUtils.isEmpty(mHbmPath);
- mView.setHbmSupported(mHbmSupported);
scrimController.addScrimChangedListener(mView);
statusBarStateController.addCallback(mView);
- // This range only consists of the minimum and maximum values, which only cover
- // non-high-brightness mode.
- float[] nitsRange = toFloatArray(resources.obtainTypedArray(
- com.android.internal.R.array.config_screenBrightnessNits));
- if (nitsRange.length < 2) {
- throw new IllegalArgumentException(
- String.format("nitsRange.length: %d. Must be >= 2", nitsRange.length));
- }
-
- // The last value of this range corresponds to the high-brightness mode.
- float[] nitsAutoBrightnessValues = toFloatArray(resources.obtainTypedArray(
- com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
- if (nitsAutoBrightnessValues.length < 2) {
- throw new IllegalArgumentException(
- String.format("nitsAutoBrightnessValues.length: %d. Must be >= 2",
- nitsAutoBrightnessValues.length));
- }
-
- mMaxNits = nitsAutoBrightnessValues[nitsAutoBrightnessValues.length - 1];
- float[] hbmNitsRange = nitsRange.clone();
- hbmNitsRange[hbmNitsRange.length - 1] = mMaxNits;
-
- // This range only consists of the minimum and maximum backlight values, which only apply
- // in non-high-brightness mode.
- float[] normalizedBacklightRange = normalizeBacklightRange(
- resources.getIntArray(
- com.android.internal.R.array.config_screenBrightnessBacklight));
- if (normalizedBacklightRange.length < 2) {
- throw new IllegalArgumentException(
- String.format("normalizedBacklightRange.length: %d. Must be >= 2",
- normalizedBacklightRange.length));
- }
- if (normalizedBacklightRange.length != nitsRange.length) {
- throw new IllegalArgumentException(
- "normalizedBacklightRange.length != nitsRange.length");
- }
-
- mBacklightToNitsSpline = Spline.createSpline(normalizedBacklightRange, nitsRange);
- mNitsToHbmBacklightSpline = Spline.createSpline(hbmNitsRange, normalizedBacklightRange);
- mDefaultBrightness = obtainDefaultBrightness(mContext);
-
- // TODO(b/160025856): move to the "dump" method.
- Log.v(TAG, String.format("ctor | mNitsRange: [%f, %f]", nitsRange[0],
- nitsRange[nitsRange.length - 1]));
- Log.v(TAG, String.format("ctor | mHbmNitsRange: [%f, %f]", hbmNitsRange[0],
- hbmNitsRange[hbmNitsRange.length - 1]));
- Log.v(TAG, String.format("ctor | mNormalizedBacklightRange: [%f, %f]",
- normalizedBacklightRange[0],
- normalizedBacklightRange[normalizedBacklightRange.length - 1]));
-
mFingerprintManager.setUdfpsOverlayController(new UdfpsOverlayController());
mIsOverlayShowing = false;
}
@@ -331,13 +243,33 @@ public class UdfpsController implements DozeReceiver {
}
private WindowManager.LayoutParams computeLayoutParams() {
+ // Default dimensions assume portrait mode.
+ mCoreLayoutParams.x = mSensorProps.sensorLocationX - mSensorProps.sensorRadius;
+ mCoreLayoutParams.y = mSensorProps.sensorLocationY - mSensorProps.sensorRadius;
+ mCoreLayoutParams.height = 2 * mSensorProps.sensorRadius;
+ mCoreLayoutParams.width = 2 * mSensorProps.sensorRadius;
+
Point p = new Point();
// Gets the size based on the current rotation of the display.
mContext.getDisplay().getRealSize(p);
- mCoreLayoutParams.width = p.x;
- mCoreLayoutParams.x = p.x;
- mCoreLayoutParams.height = p.y;
- mCoreLayoutParams.y = p.y;
+
+ // Transform dimensions if the device is in landscape mode.
+ switch (mContext.getDisplay().getRotation()) {
+ case Surface.ROTATION_90:
+ mCoreLayoutParams.x = mSensorProps.sensorLocationY - mSensorProps.sensorRadius;
+ mCoreLayoutParams.y =
+ p.y - mSensorProps.sensorLocationX - mSensorProps.sensorRadius;
+ break;
+
+ case Surface.ROTATION_270:
+ mCoreLayoutParams.x =
+ p.x - mSensorProps.sensorLocationY - mSensorProps.sensorRadius;
+ mCoreLayoutParams.y = mSensorProps.sensorLocationX - mSensorProps.sensorRadius;
+ break;
+
+ default:
+ // Do nothing to stay in portrait mode.
+ }
return mCoreLayoutParams;
}
@@ -402,36 +334,10 @@ public class UdfpsController implements DozeReceiver {
});
}
- // Returns a value in the range of [0, 255].
- private int computeScrimOpacity() {
- // Backlight setting can be NaN, -1.0f, and [0.0f, 1.0f].
- float backlightSetting = mSystemSettings.getFloatForUser(
- Settings.System.SCREEN_BRIGHTNESS_FLOAT, mDefaultBrightness,
- UserHandle.USER_CURRENT);
-
- // Constrain the backlight setting to [0.0f, 1.0f].
- float backlightValue = MathUtils.constrain(backlightSetting,
- PowerManager.BRIGHTNESS_MIN,
- PowerManager.BRIGHTNESS_MAX);
-
- // Interpolate the backlight value to nits.
- float nits = mBacklightToNitsSpline.interpolate(backlightValue);
-
- // Interpolate nits to a backlight value for a panel with enabled HBM.
- float interpolatedHbmBacklightValue = mNitsToHbmBacklightSpline.interpolate(nits);
-
- float gammaCorrectedHbmBacklightValue = (float) Math.pow(interpolatedHbmBacklightValue,
- 1.0f / DISPLAY_GAMMA);
- float scrimOpacity = PowerManager.BRIGHTNESS_MAX - gammaCorrectedHbmBacklightValue;
-
- // Interpolate the opacity value from [0.0f, 1.0f] to [0, 255].
- return BrightnessSynchronizer.brightnessFloatToInt(scrimOpacity);
- }
-
/**
* Request fingerprint scan.
*
- * This is intented to be called in response to a sensor that triggers an AOD interrupt for the
+ * This is intended to be called in response to a sensor that triggers an AOD interrupt for the
* fingerprint sensor.
*/
void onAodInterrupt(int screenX, int screenY, float major, float minor) {
@@ -451,7 +357,7 @@ public class UdfpsController implements DozeReceiver {
/**
* Cancel fingerprint scan.
*
- * This is intented to be called after the fingerprint scan triggered by the AOD interrupt
+ * This is intended to be called after the fingerprint scan triggered by the AOD interrupt
* either succeeds or fails.
*/
void onCancelAodInterrupt() {
@@ -466,65 +372,28 @@ public class UdfpsController implements DozeReceiver {
onFingerUp();
}
- protected void onFingerDown(int x, int y, float minor, float major) {
- if (mHbmSupported) {
- try {
- FileWriter fw = new FileWriter(mHbmPath);
- fw.write(mHbmEnableCommand);
- fw.close();
- } catch (IOException e) {
- mView.hideScrimAndDot();
- Log.e(TAG, "onFingerDown | failed to enable HBM: " + e.getMessage());
- }
- }
- mView.setScrimAlpha(computeScrimOpacity());
- mView.setRunAfterShowingScrimAndDot(() -> {
- mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major);
- });
- mView.showScrimAndDot();
+ // This method can be called from the UI thread.
+ private void onFingerDown(int x, int y, float minor, float major) {
+ mView.setOnIlluminatedRunnable(
+ () -> mFingerprintManager.onPointerDown(mSensorProps.sensorId, x, y, minor, major));
+ mView.startIllumination();
}
- protected void onFingerUp() {
+ // This method can be called from the UI thread.
+ private void onFingerUp() {
mFingerprintManager.onPointerUp(mSensorProps.sensorId);
- // Hiding the scrim before disabling HBM results in less noticeable flicker.
- mView.hideScrimAndDot();
- if (mHbmSupported) {
- try {
- FileWriter fw = new FileWriter(mHbmPath);
- fw.write(mHbmDisableCommand);
- fw.close();
- } catch (IOException e) {
- mView.showScrimAndDot();
- Log.e(TAG, "onFingerUp | failed to disable HBM: " + e.getMessage());
- }
- }
- }
-
- private static float obtainDefaultBrightness(Context context) {
- return MathUtils.constrain(context.getDisplay().getBrightnessDefault(),
- PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX);
+ mView.stopIllumination();
}
- private static float[] toFloatArray(TypedArray array) {
- final int n = array.length();
- float[] vals = new float[n];
- for (int i = 0; i < n; i++) {
- vals[i] = array.getFloat(i, PowerManager.BRIGHTNESS_OFF_FLOAT);
- }
- array.recycle();
- return vals;
- }
-
- private static float[] normalizeBacklightRange(int[] backlight) {
- final int n = backlight.length;
- float[] normalizedBacklight = new float[n];
- for (int i = 0; i < n; i++) {
- normalizedBacklight[i] = BrightnessSynchronizer.brightnessIntToFloat(backlight[i]);
- }
- return normalizedBacklight;
+ @Override
+ public void enableHbm(Surface surface) {
+ // Do nothing. This method can be implemented for devices that require the high-brightness
+ // mode for fingerprint illumination.
}
- protected UdfpsView getView() {
- return mView;
+ @Override
+ public void disableHbm(Surface surface) {
+ // Do nothing. This method can be implemented for devices that require the high-brightness
+ // mode for fingerprint illumination.
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
index 96ecc7bdb017..4c05b886f8a8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
@@ -28,7 +28,7 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.Rect;
+import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.text.TextUtils;
@@ -37,7 +37,6 @@ import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
-import android.view.ViewTreeObserver;
import com.android.systemui.R;
import com.android.systemui.doze.DozeReceiver;
@@ -48,68 +47,64 @@ import com.android.systemui.statusbar.phone.ScrimController;
* A full screen view with a configurable illumination dot and scrim.
*/
public class UdfpsView extends SurfaceView implements DozeReceiver,
- StatusBarStateController.StateListener, ScrimController.ScrimChangedListener {
+ StatusBarStateController.StateListener, ScrimController.ScrimChangedListener {
private static final String TAG = "UdfpsView";
- // Values in pixels.
+ /**
+ * Interface for controlling the high-brightness mode (HBM). UdfpsView can use this callback to
+ * enable the HBM while showing the fingerprint illumination, and to disable the HBM after the
+ * illumination is no longer necessary.
+ */
+ interface HbmCallback {
+ /**
+ * UdfpsView will call this to enable the HBM before drawing the illumination dot.
+ *
+ * @param surface A valid surface for which the HBM should be enabled.
+ */
+ void enableHbm(@NonNull Surface surface);
+
+ /**
+ * UdfpsView will call this to disable the HBM when the illumination is not longer needed.
+ *
+ * @param surface A valid surface for which the HBM should be disabled.
+ */
+ void disableHbm(@NonNull Surface surface);
+ }
+
+ /**
+ * This is used instead of {@link android.graphics.drawable.Drawable}, because the latter has
+ * several abstract methods that are not used here but require implementation.
+ */
+ private interface SimpleDrawable {
+ void draw(Canvas canvas);
+ }
+
+ // Radius in pixels.
private static final float SENSOR_SHADOW_RADIUS = 2.0f;
private static final int DEBUG_TEXT_SIZE_PX = 32;
- @NonNull private final Rect mScrimRect;
- @NonNull private final Paint mScrimPaint;
- @NonNull private final Paint mDebugTextPaint;
-
+ @NonNull private final SurfaceHolder mHolder;
@NonNull private final RectF mSensorRect;
@NonNull private final Paint mSensorPaint;
- private final float mSensorTouchAreaCoefficient;
+ @NonNull private final Paint mDebugTextPaint;
+ @NonNull private final SimpleDrawable mIlluminationDotDrawable;
+ @NonNull private final SimpleDrawable mClearSurfaceDrawable;
- // Stores rounded up values from mSensorRect. Necessary for APIs that only take Rect (not RecF).
- @NonNull private final Rect mTouchableRegion;
- // mInsetsListener is used to set the touchable region for our window. Our window covers the
- // whole screen, and by default its touchable region is the whole screen. We use
- // mInsetsListener to restrict the touchable region and allow the touches outside of the sensor
- // to propagate to the rest of the UI.
- @NonNull private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener;
@Nullable private UdfpsAnimation mUdfpsAnimation;
+ @Nullable private HbmCallback mHbmCallback;
+ @Nullable private Runnable mOnIlluminatedRunnable;
// Used to obtain the sensor location.
@NonNull private FingerprintSensorPropertiesInternal mSensorProps;
- private boolean mShowScrimAndDot;
- private boolean mIsHbmSupported;
+ private final float mSensorTouchAreaCoefficient;
@Nullable private String mDebugMessage;
+ private boolean mIlluminationRequested;
private int mStatusBarState;
private boolean mNotificationShadeExpanded;
private int mNotificationPanelAlpha;
- // Runnable that will be run after the illumination dot and scrim are shown.
- // The runnable is reset to null after it's executed once.
- @Nullable private Runnable mRunAfterShowingScrimAndDot;
-
- @NonNull private final SurfaceHolder.Callback mSurfaceCallback = new SurfaceHolder.Callback() {
- @Override
- public void surfaceCreated(@NonNull SurfaceHolder holder) {
- Log.d(TAG, "Surface created");
- // SurfaceView sets this to true by default. We must set it to false to allow
- // onDraw to be called
- setWillNotDraw(false);
- }
-
- @Override
- public void surfaceChanged(@NonNull SurfaceHolder holder, int format,
- int width, int height) {
-
- }
-
- @Override
- public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
- Log.d(TAG, "Surface destroyed");
- // Must not draw when the surface is destroyed
- setWillNotDraw(true);
- }
- };
-
public UdfpsView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -126,18 +121,13 @@ public class UdfpsView extends SurfaceView implements DozeReceiver,
a.recycle();
}
- getHolder().addCallback(mSurfaceCallback);
- getHolder().setFormat(PixelFormat.TRANSLUCENT);
-
- mScrimRect = new Rect();
- mScrimPaint = new Paint(0 /* flags */);
- mScrimPaint.setColor(Color.BLACK);
+ mHolder = getHolder();
+ mHolder.setFormat(PixelFormat.RGBA_8888);
mSensorRect = new RectF();
mSensorPaint = new Paint(0 /* flags */);
mSensorPaint.setAntiAlias(true);
- mSensorPaint.setColor(Color.WHITE);
- mSensorPaint.setShadowLayer(SENSOR_SHADOW_RADIUS, 0, 0, Color.BLACK);
+ mSensorPaint.setARGB(255, 255, 255, 255);
mSensorPaint.setStyle(Paint.Style.FILL);
mDebugTextPaint = new Paint();
@@ -145,16 +135,13 @@ public class UdfpsView extends SurfaceView implements DozeReceiver,
mDebugTextPaint.setColor(Color.BLUE);
mDebugTextPaint.setTextSize(DEBUG_TEXT_SIZE_PX);
- mTouchableRegion = new Rect();
- // When the device is rotated, it's important that mTouchableRegion is updated before
- // this listener is called. This listener is usually called shortly after onLayout.
- mInsetsListener = internalInsetsInfo -> {
- internalInsetsInfo.setTouchableInsets(
- ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
- internalInsetsInfo.touchableRegion.set(mTouchableRegion);
- };
+ mIlluminationDotDrawable = canvas -> canvas.drawOval(mSensorRect, mSensorPaint);
+ mClearSurfaceDrawable = canvas -> canvas.drawColor(0, PorterDuff.Mode.CLEAR);
- mShowScrimAndDot = false;
+ mIlluminationRequested = false;
+ // SurfaceView sets this to true by default. We must set it to false to allow
+ // onDraw to be called.
+ setWillNotDraw(false);
}
void setSensorProperties(@NonNull FingerprintSensorPropertiesInternal properties) {
@@ -165,6 +152,20 @@ public class UdfpsView extends SurfaceView implements DozeReceiver,
mUdfpsAnimation = animation;
}
+ /**
+ * Sets a callback that can be used to enable and disable the high-brightness mode (HBM).
+ */
+ void setHbmCallback(@Nullable HbmCallback callback) {
+ mHbmCallback = callback;
+ }
+
+ /**
+ * Sets a runnable that will be run when the first illumination frame reaches the panel.
+ * The runnable is reset to null after it is executed once.
+ */
+ void setOnIlluminatedRunnable(Runnable runnable) {
+ mOnIlluminatedRunnable = runnable;
+ }
@Override
public void dozeTimeTick() {
@@ -189,50 +190,13 @@ public class UdfpsView extends SurfaceView implements DozeReceiver,
postInvalidate();
}
- // The "h" and "w" are the display's height and width relative to its current rotation.
- protected void updateSensorRect(int h, int w) {
- // mSensorProps coordinates assume portrait mode.
- mSensorRect.set(mSensorProps.sensorLocationX - mSensorProps.sensorRadius,
- mSensorProps.sensorLocationY - mSensorProps.sensorRadius,
- mSensorProps.sensorLocationX + mSensorProps.sensorRadius,
- mSensorProps.sensorLocationY + mSensorProps.sensorRadius);
-
- // Transform mSensorRect if the device is in landscape mode.
- switch (mContext.getDisplay().getRotation()) {
- case Surface.ROTATION_90:
- //noinspection SuspiciousNameCombination
- mSensorRect.set(mSensorRect.top, h - mSensorRect.right, mSensorRect.bottom,
- h - mSensorRect.left);
- break;
- case Surface.ROTATION_270:
- //noinspection SuspiciousNameCombination
- mSensorRect.set(w - mSensorRect.bottom, mSensorRect.left, w - mSensorRect.top,
- mSensorRect.right);
- break;
- default:
- // Do nothing to stay in portrait mode.
- }
-
- if (mUdfpsAnimation != null) {
- mUdfpsAnimation.onSensorRectUpdated(new RectF(mSensorRect));
- }
- }
-
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- // Always re-compute the layout regardless of whether "changed" is true. It is usually false
- // when the device goes from landscape to seascape and vice versa, but mSensorRect and
- // its dependencies need to be recalculated to stay at the same physical location on the
- // screen.
- final int w = getLayoutParams().width;
- final int h = getLayoutParams().height;
- mScrimRect.set(0 /* left */, 0 /* top */, w, h);
- updateSensorRect(h, w);
- // Update mTouchableRegion with the rounded up values from mSensorRect. After "onLayout"
- // is finished, mTouchableRegion will be used by mInsetsListener to compute the touch
- // insets.
- mSensorRect.roundOut(mTouchableRegion);
+ mSensorRect.set(0, 0, 2 * mSensorProps.sensorRadius, 2 * mSensorProps.sensorRadius);
+ if (mUdfpsAnimation != null) {
+ mUdfpsAnimation.onSensorRectUpdated(new RectF(mSensorRect));
+ }
}
@Override
@@ -242,8 +206,6 @@ public class UdfpsView extends SurfaceView implements DozeReceiver,
// Retrieve the colors each time, since it depends on day/night mode
updateColor();
-
- getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
}
private void updateColor() {
@@ -256,56 +218,51 @@ public class UdfpsView extends SurfaceView implements DozeReceiver,
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Log.v(TAG, "onDetachedFromWindow");
- getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener);
}
+ /**
+ * Immediately draws the provided drawable on this SurfaceView's surface.
+ */
+ private void drawImmediately(@NonNull SimpleDrawable drawable) {
+ Canvas canvas = null;
+ try {
+ canvas = mHolder.lockCanvas();
+ drawable.draw(canvas);
+ } finally {
+ // Make sure the surface is never left in a bad state.
+ if (canvas != null) {
+ mHolder.unlockCanvasAndPost(canvas);
+ }
+ }
+ }
+
+ /**
+ * This onDraw will not execute if setWillNotDraw(true) is called.
+ */
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
-
- if (mShowScrimAndDot && mIsHbmSupported) {
- // Only draw the scrim if HBM is supported.
- canvas.drawRect(mScrimRect, mScrimPaint);
- }
-
- if (!TextUtils.isEmpty(mDebugMessage)) {
- canvas.drawText(mDebugMessage, 0, 160, mDebugTextPaint);
- }
-
- if (mShowScrimAndDot) {
- // draw dot (white circle)
- canvas.drawOval(mSensorRect, mSensorPaint);
- } else {
+ if (!mIlluminationRequested) {
+ if (!TextUtils.isEmpty(mDebugMessage)) {
+ canvas.drawText(mDebugMessage, 0, 160, mDebugTextPaint);
+ }
if (mUdfpsAnimation != null) {
final int alpha = shouldPauseAuth() ? 255 - mNotificationPanelAlpha : 255;
mUdfpsAnimation.setAlpha(alpha);
mUdfpsAnimation.draw(canvas);
}
}
-
- if (mShowScrimAndDot && mRunAfterShowingScrimAndDot != null) {
- post(mRunAfterShowingScrimAndDot);
- mRunAfterShowingScrimAndDot = null;
- }
}
RectF getSensorRect() {
return new RectF(mSensorRect);
}
- void setHbmSupported(boolean value) {
- mIsHbmSupported = value;
- }
-
void setDebugMessage(String message) {
mDebugMessage = message;
postInvalidate();
}
- void setRunAfterShowingScrimAndDot(Runnable runnable) {
- mRunAfterShowingScrimAndDot = runnable;
- }
-
boolean isValidTouch(float x, float y, float pressure) {
// The X and Y coordinates of the sensor's center.
final float cx = mSensorRect.centerX();
@@ -332,21 +289,41 @@ public class UdfpsView extends SurfaceView implements DozeReceiver,
|| mStatusBarState == FULLSCREEN_USER_SWITCHER;
}
- void setScrimAlpha(int alpha) {
- mScrimPaint.setAlpha(alpha);
+ boolean isIlluminationRequested() {
+ return mIlluminationRequested;
}
- boolean isShowScrimAndDot() {
- return mShowScrimAndDot;
- }
+ void startIllumination() {
+ mIlluminationRequested = true;
- void showScrimAndDot() {
- mShowScrimAndDot = true;
- invalidate();
+ // Disable onDraw to prevent overriding the illumination dot with the regular UI.
+ setWillNotDraw(true);
+
+ if (mHbmCallback != null && mHolder.getSurface().isValid()) {
+ mHbmCallback.enableHbm(mHolder.getSurface());
+ }
+ drawImmediately(mIlluminationDotDrawable);
+
+ if (mOnIlluminatedRunnable != null) {
+ // No framework API can reliably tell when a frame reaches the panel. A timeout is the
+ // safest solution. The frame should be displayed within 3 refresh cycles, which on a
+ // 60 Hz panel equates to 50 milliseconds.
+ postDelayed(mOnIlluminatedRunnable, 50 /* delayMillis */);
+ mOnIlluminatedRunnable = null;
+ }
}
- void hideScrimAndDot() {
- mShowScrimAndDot = false;
+ void stopIllumination() {
+ mIlluminationRequested = false;
+
+ if (mHbmCallback != null && mHolder.getSurface().isValid()) {
+ mHbmCallback.disableHbm(mHolder.getSurface());
+ }
+ // It may be necessary to clear the surface for the HBM changes to apply.
+ drawImmediately(mClearSurfaceDrawable);
+
+ // Enable onDraw to allow the regular UI to be drawn.
+ setWillNotDraw(false);
invalidate();
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 4d697005be7b..b0067cd15c1b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -29,6 +29,7 @@ import com.android.systemui.appops.dagger.AppOpsModule;
import com.android.systemui.assist.AssistModule;
import com.android.systemui.classifier.FalsingModule;
import com.android.systemui.controls.dagger.ControlsModule;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.demomode.dagger.DemoModeModule;
import com.android.systemui.doze.dagger.DozeComponent;
import com.android.systemui.dump.DumpManager;
@@ -75,6 +76,7 @@ import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
import java.util.Optional;
+import java.util.concurrent.Executor;
import dagger.Binds;
import dagger.BindsOptionalOf;
@@ -153,6 +155,7 @@ public abstract class SystemUIModule {
@Binds
abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
+ // TODO: This should provided by the WM component
/** Provides Optional of BubbleManager */
@SysUISingleton
@Provides
@@ -166,11 +169,12 @@ public abstract class SystemUIModule {
ZenModeController zenModeController, NotificationLockscreenUserManager notifUserManager,
NotificationGroupManagerLegacy groupManager, NotificationEntryManager entryManager,
NotifPipeline notifPipeline, SysUiState sysUiState, FeatureFlags featureFlags,
- DumpManager dumpManager) {
+ DumpManager dumpManager, @Main Executor sysuiMainExecutor) {
return Optional.ofNullable(BubblesManager.create(context, bubblesOptional,
notificationShadeWindowController, statusBarStateController, shadeController,
configurationController, statusBarService, notificationManager,
interruptionStateProvider, zenModeController, notifUserManager,
- groupManager, entryManager, notifPipeline, sysUiState, featureFlags, dumpManager));
+ groupManager, entryManager, notifPipeline, sysUiState, featureFlags, dumpManager,
+ sysuiMainExecutor));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 34d1f6e1789c..fcb5da3f8c52 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -28,6 +28,7 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.containsType;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
@@ -994,6 +995,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
return MODE_LIGHTS_OUT_TRANSPARENT;
} else if ((appearance & APPEARANCE_OPAQUE_NAVIGATION_BARS) != 0) {
return MODE_OPAQUE;
+ } else if ((appearance & APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS) != 0) {
+ return MODE_SEMI_TRANSPARENT;
} else {
return MODE_TRANSPARENT;
}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
index 66c535f869f0..c3d6a848202f 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
@@ -24,7 +24,6 @@ import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.view.WindowInsets
import android.widget.ImageView
@@ -66,9 +65,8 @@ class PrivacyDialog(
super.onCreate(savedInstanceState)
window?.apply {
attributes.fitInsetsTypes = attributes.fitInsetsTypes or WindowInsets.Type.statusBars()
- setLayout(MATCH_PARENT, WRAP_CONTENT)
+ setLayout(context.resources.getDimensionPixelSize(R.dimen.qs_panel_width), WRAP_CONTENT)
setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL)
- setBackgroundDrawable(null)
}
setContentView(R.layout.privacy_dialog)
@@ -130,7 +128,7 @@ class PrivacyDialog(
)
} ?: firstLine
newView.requireViewById<TextView>(R.id.text).text = finalText
- newView.requireViewById<View>(R.id.link).apply {
+ newView.apply {
tag = element.type.permGroupName
setOnClickListener(clickListener)
}
@@ -154,9 +152,7 @@ class PrivacyDialog(
}
private val clickListener = View.OnClickListener { v ->
- if (v.id == R.id.link) {
- v.tag?.let { activityStarter(it as String) }
- }
+ v.tag?.let { activityStarter(it as String) }
}
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index d6413ed63e6e..0a7eea487ee8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -602,7 +602,7 @@ public class ScreenshotController {
private void runScrollCapture(ScrollCaptureClient.Connection connection) {
cancelTimeout();
ScrollCaptureController controller = new ScrollCaptureController(mContext, connection,
- mMainExecutor, mBgExecutor, mImageExporter);
+ mMainExecutor, mBgExecutor, mImageExporter, mUiEventLogger);
controller.attach(mWindow);
controller.start(new TakeScreenshotService.RequestCallback() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java
index f1fb6884188f..5cf018813133 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java
@@ -63,7 +63,15 @@ public enum ScreenshotEvent implements UiEventLogger.UiEventEnum {
@UiEvent(doc = "screenshot swiped to dismiss")
SCREENSHOT_SWIPE_DISMISSED(656),
@UiEvent(doc = "screenshot reentered for new screenshot")
- SCREENSHOT_REENTERED(640);
+ SCREENSHOT_REENTERED(640),
+ @UiEvent(doc = "Long screenshot button was shown to the user")
+ SCREENSHOT_LONG_SCREENSHOT_IMPRESSION(687),
+ @UiEvent(doc = "User has requested a long screenshot")
+ SCREENSHOT_LONG_SCREENSHOT_REQUESTED(688),
+ @UiEvent(doc = "User has shared a long screenshot")
+ SCREENSHOT_LONG_SCREENSHOT_SHARE(689),
+ @UiEvent(doc = "User has sent a long screenshot to the editor")
+ SCREENSHOT_LONG_SCREENSHOT_EDIT(690);
private final int mId;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index bf86b68893c8..3bc5ebf8c64e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
@@ -192,14 +192,14 @@ public class ScreenshotView extends FrameLayout implements
if (DEBUG_SCROLL) {
Log.d(TAG, "Showing Scroll option");
}
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_IMPRESSION);
mScrollChip.setVisibility(VISIBLE);
mScrollChip.setOnClickListener((v) -> {
if (DEBUG_INPUT) {
Log.d(TAG, "scroll chip tapped");
}
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_REQUESTED);
onClick.run();
- // TODO Logging, store event consumer to a field
- //onElementTapped.accept(ScreenshotEvent.SCREENSHOT_SCROLL_TAPPED);
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
index 9be3566e1f63..176a2c78796b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScrollCaptureController.java
@@ -29,6 +29,7 @@ import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
import android.view.Window;
import android.widget.ImageView;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.screenshot.ScrollCaptureClient.Connection;
import com.android.systemui.screenshot.ScrollCaptureClient.Session;
@@ -58,6 +59,7 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
private final Executor mBgExecutor;
private final ImageExporter mImageExporter;
private final ImageTileSet mImageTileSet;
+ private final UiEventLogger mUiEventLogger;
private ZonedDateTime mCaptureTime;
private UUID mRequestId;
@@ -72,12 +74,13 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
private Runnable mPendingAction;
public ScrollCaptureController(Context context, Connection connection, Executor uiExecutor,
- Executor bgExecutor, ImageExporter exporter) {
+ Executor bgExecutor, ImageExporter exporter, UiEventLogger uiEventLogger) {
mContext = context;
mConnection = connection;
mUiExecutor = uiExecutor;
mBgExecutor = bgExecutor;
mImageExporter = exporter;
+ mUiEventLogger = uiEventLogger;
mImageTileSet = new ImageTileSet();
}
@@ -136,10 +139,12 @@ public class ScrollCaptureController implements OnComputeInternalInsetsListener
disableButtons();
finish();
} else if (id == R.id.edit) {
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_EDIT);
v.setPressed(true);
disableButtons();
edit();
} else if (id == R.id.share) {
+ mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_SHARE);
v.setPressed(true);
disableButtons();
share();
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java
index 11ee94c97d7c..8dcc8b46f024 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessControllerSettings.java
@@ -17,6 +17,7 @@
package com.android.systemui.settings.brightness;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.util.settings.SecureSettings;
import javax.inject.Inject;
@@ -28,11 +29,13 @@ import javax.inject.Inject;
public class BrightnessControllerSettings {
private static final String THICK_BRIGHTNESS_SLIDER = "sysui_thick_brightness";
+ private final FeatureFlags mFeatureFlags;
private final boolean mUseThickSlider;
private final boolean mUseMirrorOnThickSlider;
@Inject
- public BrightnessControllerSettings(SecureSettings settings) {
+ public BrightnessControllerSettings(SecureSettings settings, FeatureFlags featureFlags) {
+ mFeatureFlags = featureFlags;
mUseThickSlider = settings.getInt(THICK_BRIGHTNESS_SLIDER, 0) != 0;
mUseMirrorOnThickSlider = settings.getInt(THICK_BRIGHTNESS_SLIDER, 0) != 2;
}
@@ -41,11 +44,11 @@ public class BrightnessControllerSettings {
// restart systemui after changing it.
/** */
boolean useThickSlider() {
- return mUseThickSlider;
+ return mUseThickSlider && mFeatureFlags.useNewBrightnessSlider();
}
/** */
boolean useMirrorOnThickSlider() {
- return mUseMirrorOnThickSlider;
+ return !useThickSlider() || (useThickSlider() && mUseMirrorOnThickSlider);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
index 30b31580e130..e7b60c3a0d67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java
@@ -61,4 +61,13 @@ public class FeatureFlags {
public boolean isKeyguardLayoutEnabled() {
return mFlagReader.isEnabled(R.bool.flag_keyguard_layout);
}
+
+ /** b/178485354 */
+ public boolean useNewBrightnessSlider() {
+ return mFlagReader.isEnabled(R.bool.flag_brightness_slider);
+ }
+
+ public boolean isPeopleTileEnabled() {
+ return mFlagReader.isEnabled(R.bool.flag_conversations);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index 7f30009cda6f..6023b7f6f4f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -26,25 +26,41 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
import android.util.AttributeSet;
import android.view.View;
import androidx.core.graphics.ColorUtils;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.colorextraction.drawable.ScrimDrawable;
+import java.util.concurrent.Executor;
+
+
/**
- * A view which can draw a scrim
+ * A view which can draw a scrim. This view maybe be used in multiple windows running on different
+ * threads, but is controlled by {@link com.android.systemui.statusbar.phone.ScrimController} so we
+ * need to be careful to synchronize when necessary.
*/
public class ScrimView extends View {
+ private final Object mColorLock = new Object();
+
+ @GuardedBy("mColorLock")
private final ColorExtractor.GradientColors mColors;
+ // Used only for returning the colors
+ private final ColorExtractor.GradientColors mTmpColors = new ColorExtractor.GradientColors();
private float mViewAlpha = 1.0f;
private Drawable mDrawable;
private PorterDuffColorFilter mColorFilter;
private int mTintColor;
private Runnable mChangeRunnable;
+ private Executor mChangeRunnableExecutor;
+ private Executor mExecutor;
+ private Looper mExecutorLooper;
public ScrimView(Context context) {
this(context, null);
@@ -64,7 +80,16 @@ public class ScrimView extends View {
mDrawable = new ScrimDrawable();
mDrawable.setCallback(this);
mColors = new ColorExtractor.GradientColors();
- updateColorWithTint(false);
+ mExecutorLooper = Looper.myLooper();
+ mExecutor = Runnable::run;
+ executeOnExecutor(() -> {
+ updateColorWithTint(false);
+ });
+ }
+
+ public void setExecutor(Executor executor, Looper looper) {
+ mExecutor = executor;
+ mExecutorLooper = looper;
}
@Override
@@ -75,11 +100,13 @@ public class ScrimView extends View {
}
public void setDrawable(Drawable drawable) {
- mDrawable = drawable;
- mDrawable.setCallback(this);
- mDrawable.setBounds(getLeft(), getTop(), getRight(), getBottom());
- mDrawable.setAlpha((int) (255 * mViewAlpha));
- invalidate();
+ executeOnExecutor(() -> {
+ mDrawable = drawable;
+ mDrawable.setCallback(this);
+ mDrawable.setBounds(getLeft(), getTop(), getRight(), getBottom());
+ mDrawable.setAlpha((int) (255 * mViewAlpha));
+ invalidate();
+ });
}
@Override
@@ -99,6 +126,13 @@ public class ScrimView extends View {
}
}
+ @Override
+ public void setClickable(boolean clickable) {
+ executeOnExecutor(() -> {
+ super.setClickable(clickable);
+ });
+ }
+
public void setColors(@NonNull ColorExtractor.GradientColors colors) {
setColors(colors, false);
}
@@ -107,11 +141,15 @@ public class ScrimView extends View {
if (colors == null) {
throw new IllegalArgumentException("Colors cannot be null");
}
- if (mColors.equals(colors)) {
- return;
- }
- mColors.set(colors);
- updateColorWithTint(animated);
+ executeOnExecutor(() -> {
+ synchronized(mColorLock) {
+ if (mColors.equals(colors)) {
+ return;
+ }
+ mColors.set(colors);
+ }
+ updateColorWithTint(animated);
+ });
}
@VisibleForTesting
@@ -120,7 +158,10 @@ public class ScrimView extends View {
}
public ColorExtractor.GradientColors getColors() {
- return mColors;
+ synchronized(mColorLock) {
+ mTmpColors.set(mColors);
+ }
+ return mTmpColors;
}
public void setTint(int color) {
@@ -128,11 +169,13 @@ public class ScrimView extends View {
}
public void setTint(int color, boolean animated) {
- if (mTintColor == color) {
- return;
- }
- mTintColor = color;
- updateColorWithTint(animated);
+ executeOnExecutor(() -> {
+ if (mTintColor == color) {
+ return;
+ }
+ mTintColor = color;
+ updateColorWithTint(animated);
+ });
}
private void updateColorWithTint(boolean animated) {
@@ -160,7 +203,7 @@ public class ScrimView extends View {
}
if (mChangeRunnable != null) {
- mChangeRunnable.run();
+ mChangeRunnableExecutor.execute(mChangeRunnable);
}
}
@@ -184,26 +227,37 @@ public class ScrimView extends View {
if (isNaN(alpha)) {
throw new IllegalArgumentException("alpha cannot be NaN: " + alpha);
}
- if (alpha != mViewAlpha) {
- mViewAlpha = alpha;
+ executeOnExecutor(() -> {
+ if (alpha != mViewAlpha) {
+ mViewAlpha = alpha;
- mDrawable.setAlpha((int) (255 * alpha));
- if (mChangeRunnable != null) {
- mChangeRunnable.run();
+ mDrawable.setAlpha((int) (255 * alpha));
+ if (mChangeRunnable != null) {
+ mChangeRunnableExecutor.execute(mChangeRunnable);
+ }
}
- }
+ });
}
public float getViewAlpha() {
return mViewAlpha;
}
- public void setChangeRunnable(Runnable changeRunnable) {
+ public void setChangeRunnable(Runnable changeRunnable, Executor changeRunnableExecutor) {
mChangeRunnable = changeRunnable;
+ mChangeRunnableExecutor = changeRunnableExecutor;
}
@Override
protected boolean canReceivePointerEvents() {
return false;
}
+
+ private void executeOnExecutor(Runnable r) {
+ if (mExecutor == null || Looper.myLooper() == mExecutorLooper) {
+ r.run();
+ } else {
+ mExecutor.execute(r);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java b/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
index 1ec043cb7670..e4ae560ba69b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SuperStatusBarViewFactory.java
@@ -23,8 +23,6 @@ import android.view.ViewGroup;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
-import com.android.systemui.statusbar.phone.LockIcon;
-import com.android.systemui.statusbar.phone.LockscreenLockIconController;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
import com.android.systemui.statusbar.phone.StatusBarWindowView;
@@ -41,7 +39,6 @@ public class SuperStatusBarViewFactory {
private final Context mContext;
private final InjectionInflationController mInjectionInflationController;
- private final LockscreenLockIconController mLockIconController;
private final NotificationShelfComponent.Builder mNotificationShelfComponentBuilder;
private NotificationShadeWindowView mNotificationShadeWindowView;
@@ -51,11 +48,9 @@ public class SuperStatusBarViewFactory {
@Inject
public SuperStatusBarViewFactory(Context context,
InjectionInflationController injectionInflationController,
- NotificationShelfComponent.Builder notificationShelfComponentBuilder,
- LockscreenLockIconController lockIconController) {
+ NotificationShelfComponent.Builder notificationShelfComponentBuilder) {
mContext = context;
mInjectionInflationController = injectionInflationController;
- mLockIconController = lockIconController;
mNotificationShelfComponentBuilder = notificationShelfComponentBuilder;
}
@@ -77,10 +72,6 @@ public class SuperStatusBarViewFactory {
throw new IllegalStateException(
"R.layout.super_notification_shade could not be properly inflated");
}
- LockIcon lockIcon = mNotificationShadeWindowView.findViewById(R.id.lock_icon);
- if (lockIcon != null) {
- mLockIconController.attach(lockIcon);
- }
return mNotificationShadeWindowView;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
index 4fde1187477c..db49e4476a99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/init/NotifPipelineInitializer.java
@@ -21,7 +21,6 @@ import android.util.Log;
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
-import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
@@ -50,7 +49,6 @@ public class NotifPipelineInitializer implements Dumpable {
private final ShadeListBuilder mListBuilder;
private final NotifCoordinators mNotifPluggableCoordinators;
private final NotifInflaterImpl mNotifInflater;
- private final PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
private final DumpManager mDumpManager;
private final ShadeViewManagerFactory mShadeViewManagerFactory;
private final FeatureFlags mFeatureFlags;
@@ -64,7 +62,6 @@ public class NotifPipelineInitializer implements Dumpable {
ShadeListBuilder listBuilder,
NotifCoordinators notifCoordinators,
NotifInflaterImpl notifInflater,
- PeopleSpaceWidgetManager peopleSpaceWidgetManager,
DumpManager dumpManager,
ShadeViewManagerFactory shadeViewManagerFactory,
FeatureFlags featureFlags) {
@@ -75,7 +72,6 @@ public class NotifPipelineInitializer implements Dumpable {
mNotifPluggableCoordinators = notifCoordinators;
mDumpManager = dumpManager;
mNotifInflater = notifInflater;
- mPeopleSpaceWidgetManager = peopleSpaceWidgetManager;
mShadeViewManagerFactory = shadeViewManagerFactory;
mFeatureFlags = featureFlags;
}
@@ -103,7 +99,6 @@ public class NotifPipelineInitializer implements Dumpable {
mListBuilder.attach(mNotifCollection);
mNotifCollection.attach(mGroupCoalescer);
mGroupCoalescer.attach(notificationService);
- mPeopleSpaceWidgetManager.attach(notificationService);
Log.d(TAG, "Notif pipeline initialized");
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 54ce4ede9770..0ad6507fb01e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.init
import android.service.notification.StatusBarNotification
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.people.widget.PeopleSpaceWidgetManager
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption
import com.android.systemui.statusbar.FeatureFlags
import com.android.systemui.statusbar.NotificationListener
@@ -73,7 +74,8 @@ class NotificationsControllerImpl @Inject constructor(
private val headsUpController: HeadsUpController,
private val headsUpViewBinder: HeadsUpViewBinder,
private val clickerBuilder: NotificationClicker.Builder,
- private val animatedImageNotificationManager: AnimatedImageNotificationManager
+ private val animatedImageNotificationManager: AnimatedImageNotificationManager,
+ private val peopleSpaceWidgetManager: PeopleSpaceWidgetManager
) : NotificationsController {
override fun initialize(
@@ -126,6 +128,10 @@ class NotificationsControllerImpl @Inject constructor(
entryManager.attach(notificationListener)
}
+
+ if (featureFlags.isPeopleTileEnabled) {
+ peopleSpaceWidgetManager.attach(notificationListener)
+ }
}
override fun dump(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index e1eaf3c17357..f289b9f20211 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -71,7 +71,7 @@ public final class DozeServiceHost implements DozeHost {
"persist.sysui.wake_performs_auth", true);
private boolean mDozingRequested;
private boolean mPulsing;
- private WakefulnessLifecycle mWakefulnessLifecycle;
+ private final WakefulnessLifecycle mWakefulnessLifecycle;
private final SysuiStatusBarStateController mStatusBarStateController;
private final DeviceProvisionedController mDeviceProvisionedController;
private final HeadsUpManagerPhone mHeadsUpManagerPhone;
@@ -86,9 +86,8 @@ public final class DozeServiceHost implements DozeHost {
private final NotificationShadeWindowController mNotificationShadeWindowController;
private final NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
- private final LockscreenLockIconController mLockscreenLockIconController;
private final AuthController mAuthController;
- private NotificationIconAreaController mNotificationIconAreaController;
+ private final NotificationIconAreaController mNotificationIconAreaController;
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private NotificationPanelViewController mNotificationPanel;
private View mAmbientIndicationContainer;
@@ -109,7 +108,6 @@ public final class DozeServiceHost implements DozeHost {
PulseExpansionHandler pulseExpansionHandler,
NotificationShadeWindowController notificationShadeWindowController,
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
- LockscreenLockIconController lockscreenLockIconController,
AuthController authController,
NotificationIconAreaController notificationIconAreaController) {
super();
@@ -129,7 +127,6 @@ public final class DozeServiceHost implements DozeHost {
mPulseExpansionHandler = pulseExpansionHandler;
mNotificationShadeWindowController = notificationShadeWindowController;
mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
- mLockscreenLockIconController = lockscreenLockIconController;
mAuthController = authController;
mNotificationIconAreaController = notificationIconAreaController;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
index eceac3240ebc..4b70de997906 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenLockIconController.java
@@ -37,12 +37,10 @@ import androidx.annotation.Nullable;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.settingslib.Utils;
import com.android.systemui.R;
-import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -52,18 +50,20 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator.WakeUpListener;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
+import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.ViewController;
import java.util.Optional;
import javax.inject.Inject;
-/** Controls the {@link LockIcon} in the lockscreen. */
-@SysUISingleton
-public class LockscreenLockIconController {
+/** Controls the {@link LockIcon} on the lockscreen. */
+@StatusBarComponent.StatusBarScope
+public class LockscreenLockIconController extends ViewController<LockIcon> {
private final LockscreenGestureLogger mLockscreenGestureLogger;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -79,7 +79,6 @@ public class LockscreenLockIconController {
private final KeyguardStateController mKeyguardStateController;
private final Resources mResources;
private final HeadsUpManagerPhone mHeadsUpManagerPhone;
- private final KeyguardSecurityModel mKeyguardSecurityModel;
private boolean mKeyguardShowing;
private boolean mKeyguardJustShown;
private boolean mBlockUpdates;
@@ -92,231 +91,13 @@ public class LockscreenLockIconController {
private boolean mBouncerShowingScrimmed;
private boolean mFingerprintUnlock;
private int mStatusBarState = StatusBarState.SHADE;
- private LockIcon mLockIcon;
-
- private View.OnAttachStateChangeListener mOnAttachStateChangeListener =
- new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
- mStatusBarStateController.addCallback(mSBStateListener);
- mConfigurationController.addCallback(mConfigurationListener);
- mNotificationWakeUpCoordinator.addListener(mWakeUpListener);
- mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
- mKeyguardStateController.addCallback(mKeyguardMonitorCallback);
-
- mDockManager.ifPresent(dockManager -> dockManager.addListener(mDockEventListener));
-
- mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
- mConfigurationListener.onThemeChanged();
-
- updateColor();
- update();
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- mStatusBarStateController.removeCallback(mSBStateListener);
- mConfigurationController.removeCallback(mConfigurationListener);
- mNotificationWakeUpCoordinator.removeListener(mWakeUpListener);
- mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
- mKeyguardStateController.removeCallback(mKeyguardMonitorCallback);
-
- mDockManager.ifPresent(dockManager -> dockManager.removeListener(mDockEventListener));
- }
- };
-
- private final StatusBarStateController.StateListener mSBStateListener =
- new StatusBarStateController.StateListener() {
- @Override
- public void onDozingChanged(boolean isDozing) {
- setDozing(isDozing);
- }
-
- @Override
- public void onDozeAmountChanged(float linear, float eased) {
- if (mLockIcon != null) {
- mLockIcon.setDozeAmount(eased);
- }
- }
-
- @Override
- public void onStateChanged(int newState) {
- setStatusBarState(newState);
- }
- };
-
- private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
- private int mDensity;
-
- @Override
- public void onUiModeChanged() {
- updateColor();
- }
-
- @Override
- public void onOverlayChanged() {
- updateColor();
- }
-
- @Override
- public void onDensityOrFontScaleChanged() {
- if (mLockIcon == null) {
- return;
- }
-
- ViewGroup.LayoutParams lp = mLockIcon.getLayoutParams();
- if (lp == null) {
- return;
- }
- lp.width = mLockIcon.getResources().getDimensionPixelSize(R.dimen.keyguard_lock_width);
- lp.height = mLockIcon.getResources().getDimensionPixelSize(
- R.dimen.keyguard_lock_height);
- mLockIcon.setLayoutParams(lp);
- update(true /* force */);
- }
-
- @Override
- public void onLocaleListChanged() {
- if (mLockIcon == null) {
- return;
- }
-
- mLockIcon.setContentDescription(
- mLockIcon.getResources().getText(R.string.accessibility_unlock_button));
- update(true /* force */);
- }
-
- @Override
- public void onConfigChanged(Configuration newConfig) {
- final int density = newConfig.densityDpi;
- if (density != mDensity) {
- mDensity = density;
- update();
- }
- }
- };
-
- private final WakeUpListener mWakeUpListener = new WakeUpListener() {
- @Override
- public void onPulseExpansionChanged(boolean expandingChanged) {
- }
-
- @Override
- public void onFullyHiddenChanged(boolean isFullyHidden) {
- if (mKeyguardBypassController.getBypassEnabled()) {
- boolean changed = updateIconVisibility();
- if (changed) {
- update();
- }
- }
- }
- };
-
- private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
- new KeyguardUpdateMonitorCallback() {
- @Override
- public void onSimStateChanged(int subId, int slotId, int simState) {
- mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
- update();
- }
-
- @Override
- public void onKeyguardVisibilityChanged(boolean showing) {
- update();
- }
-
- @Override
- public void onBiometricRunningStateChanged(boolean running,
- BiometricSourceType biometricSourceType) {
- update();
- }
-
- @Override
- public void onStrongAuthStateChanged(int userId) {
- update();
- }
- };
-
- private final DockManager.DockEventListener mDockEventListener =
- event -> {
- boolean docked =
- event == DockManager.STATE_DOCKED || event == DockManager.STATE_DOCKED_HIDE;
- if (docked != mDocked) {
- mDocked = docked;
- update();
- }
- };
-
- private final KeyguardStateController.Callback mKeyguardMonitorCallback =
- new KeyguardStateController.Callback() {
- @Override
- public void onKeyguardShowingChanged() {
- boolean force = false;
- boolean wasShowing = mKeyguardShowing;
- mKeyguardShowing = mKeyguardStateController.isShowing();
- if (!wasShowing && mKeyguardShowing && mBlockUpdates) {
- mBlockUpdates = false;
- force = true;
- }
- if (!wasShowing && mKeyguardShowing) {
- setBouncerHideAmount(KeyguardBouncer.EXPANSION_HIDDEN);
- mKeyguardJustShown = true;
- }
- update(force);
- }
-
- @Override
- public void onKeyguardFadingAwayChanged() {
- if (!mKeyguardStateController.isKeyguardFadingAway()) {
- if (mBlockUpdates) {
- mBlockUpdates = false;
- update(true /* force */);
- }
- }
- }
-
- @Override
- public void onUnlockedChanged() {
- update();
- }
- };
-
- private final View.AccessibilityDelegate mAccessibilityDelegate =
- new View.AccessibilityDelegate() {
- @Override
- public void onInitializeAccessibilityNodeInfo(View host,
- AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(host, info);
- boolean fingerprintRunning =
- mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
- // Only checking if unlocking with Biometric is allowed (no matter strong or
- // non-strong as long as primary auth, i.e. PIN/pattern/password, is not
- // required), so it's ok to pass true for isStrongBiometric to
- // isUnlockingWithBiometricAllowed() to bypass the check of whether non-strong
- // biometric is allowed
- boolean unlockingAllowed = mKeyguardUpdateMonitor
- .isUnlockingWithBiometricAllowed(true /* isStrongBiometric */);
- if (fingerprintRunning && unlockingAllowed) {
- AccessibilityNodeInfo.AccessibilityAction unlock =
- new AccessibilityNodeInfo.AccessibilityAction(
- AccessibilityNodeInfo.ACTION_CLICK,
- mResources.getString(
- R.string.accessibility_unlock_without_fingerprint));
- info.addAction(unlock);
- info.setHintText(mResources.getString(
- R.string.accessibility_waiting_for_fingerprint));
- } else if (getState() == STATE_SCANNING_FACE) {
- //Avoid 'button' to be spoken for scanning face
- info.setClassName(LockIcon.class.getName());
- info.setContentDescription(mResources.getString(
- R.string.accessibility_scanning_face));
- }
- }
- };
private int mLastState;
+ private boolean mDozing;
@Inject
- public LockscreenLockIconController(LockscreenGestureLogger lockscreenGestureLogger,
+ public LockscreenLockIconController(
+ @Nullable LockIcon view,
+ LockscreenGestureLogger lockscreenGestureLogger,
KeyguardUpdateMonitor keyguardUpdateMonitor,
LockPatternUtils lockPatternUtils,
ShadeController shadeController,
@@ -329,8 +110,8 @@ public class LockscreenLockIconController {
@Nullable DockManager dockManager,
KeyguardStateController keyguardStateController,
@Main Resources resources,
- HeadsUpManagerPhone headsUpManagerPhone,
- KeyguardSecurityModel keyguardSecurityModel) {
+ HeadsUpManagerPhone headsUpManagerPhone) {
+ super(view);
mLockscreenGestureLogger = lockscreenGestureLogger;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
@@ -345,32 +126,52 @@ public class LockscreenLockIconController {
mKeyguardStateController = keyguardStateController;
mResources = resources;
mHeadsUpManagerPhone = headsUpManagerPhone;
- mKeyguardSecurityModel = keyguardSecurityModel;
+
+ if (view == null) {
+ return;
+ }
mKeyguardIndicationController.setLockIconController(this);
}
- /**
- * Associate the controller with a {@link LockIcon}
- *
- * TODO: change to an init method and inject the view.
- */
- public void attach(LockIcon lockIcon) {
- mLockIcon = lockIcon;
-
- mLockIcon.setOnClickListener(this::handleClick);
- mLockIcon.setOnLongClickListener(this::handleLongClick);
- mLockIcon.setAccessibilityDelegate(mAccessibilityDelegate);
-
- if (mLockIcon.isAttachedToWindow()) {
- mOnAttachStateChangeListener.onViewAttachedToWindow(mLockIcon);
+ @Override
+ protected void onInit() {
+ if (mView == null) {
+ return;
}
- mLockIcon.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
+ mView.setOnClickListener(this::handleClick);
+ mView.setOnLongClickListener(this::handleLongClick);
+ mView.setAccessibilityDelegate(mAccessibilityDelegate);
+ }
+
+ @Override
+ protected void onViewAttached() {
setStatusBarState(mStatusBarStateController.getState());
+ mDozing = mStatusBarStateController.isDozing();
+ mStatusBarStateController.addCallback(mSBStateListener);
+ mConfigurationController.addCallback(mConfigurationListener);
+ mNotificationWakeUpCoordinator.addListener(mWakeUpListener);
+ mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
+ mKeyguardStateController.addCallback(mKeyguardMonitorCallback);
+
+ mDockManager.ifPresent(dockManager -> dockManager.addListener(mDockEventListener));
+
+ mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
+ mConfigurationListener.onThemeChanged();
+
+ updateColor();
+ update();
}
- public LockIcon getView() {
- return mLockIcon;
+ @Override
+ protected void onViewDetached() {
+ mStatusBarStateController.removeCallback(mSBStateListener);
+ mConfigurationController.removeCallback(mConfigurationListener);
+ mNotificationWakeUpCoordinator.removeListener(mWakeUpListener);
+ mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
+ mKeyguardStateController.removeCallback(mKeyguardMonitorCallback);
+
+ mDockManager.ifPresent(dockManager -> dockManager.removeListener(mDockEventListener));
}
/**
@@ -430,31 +231,30 @@ public class LockscreenLockIconController {
}
private void updateColor() {
- if (mLockIcon == null) {
+ if (mView == null) {
return;
}
-
int iconColor = -1;
if (mBouncerHiddenAmount == KeyguardBouncer.EXPANSION_VISIBLE) {
- TypedArray typedArray = mLockIcon.getContext().getTheme().obtainStyledAttributes(
+ TypedArray typedArray = mView.getContext().getTheme().obtainStyledAttributes(
null, new int[]{ android.R.attr.textColorPrimary }, 0, 0);
iconColor = typedArray.getColor(0, Color.WHITE);
typedArray.recycle();
} else if (mBouncerHiddenAmount == KeyguardBouncer.EXPANSION_HIDDEN) {
iconColor = Utils.getColorAttrDefaultColor(
- mLockIcon.getContext(), com.android.systemui.R.attr.wallpaperTextColor);
+ mView.getContext(), com.android.systemui.R.attr.wallpaperTextColor);
} else {
// bouncer is transitioning
- TypedArray typedArray = mLockIcon.getContext().getTheme().obtainStyledAttributes(
+ TypedArray typedArray = mView.getContext().getTheme().obtainStyledAttributes(
null, new int[]{ android.R.attr.textColorPrimary }, 0, 0);
int bouncerIconColor = typedArray.getColor(0, Color.WHITE);
typedArray.recycle();
int keyguardIconColor = Utils.getColorAttrDefaultColor(
- mLockIcon.getContext(), com.android.systemui.R.attr.wallpaperTextColor);
+ mView.getContext(), com.android.systemui.R.attr.wallpaperTextColor);
iconColor = (int) new ArgbEvaluator().evaluate(
mBouncerHiddenAmount, bouncerIconColor, keyguardIconColor);
}
- mLockIcon.updateColor(iconColor);
+ mView.updateColor(iconColor);
}
/**
@@ -497,14 +297,16 @@ public class LockscreenLockIconController {
}
private void update(boolean force) {
+ if (mView == null) {
+ return;
+ }
int state = getState();
boolean shouldUpdate = mLastState != state || force;
if (mBlockUpdates && canBlockUpdates()) {
shouldUpdate = false;
}
- if (shouldUpdate && mLockIcon != null && mLockIcon.getVisibility() != GONE) {
- mLockIcon.update(state,
- mStatusBarStateController.isDozing(), mKeyguardJustShown);
+ if (shouldUpdate && mView.getVisibility() != GONE) {
+ mView.update(state, mDozing, mKeyguardJustShown);
}
mLastState = state;
mKeyguardJustShown = false;
@@ -531,10 +333,6 @@ public class LockscreenLockIconController {
return mKeyguardShowing || mKeyguardStateController.isKeyguardFadingAway();
}
- private void setDozing(boolean isDozing) {
- update();
- }
-
/** Set the StatusBarState. */
private void setStatusBarState(int statusBarState) {
mStatusBarState = statusBarState;
@@ -546,17 +344,16 @@ public class LockscreenLockIconController {
* @return true if the visibility changed
*/
private boolean updateIconVisibility() {
- if (mLockIcon == null) {
+ if (mView == null) {
return false;
}
-
- if (!mKeyguardUpdateMonitor.shouldShowLockIcon()) {
- boolean changed = mLockIcon.getVisibility() != GONE;
- mLockIcon.setVisibility(GONE);
+ if (!mKeyguardUpdateMonitor.canShowLockIcon()) {
+ boolean changed = mView.getVisibility() != GONE;
+ mView.setVisibility(GONE);
return changed;
}
- boolean onAodOrDocked = mStatusBarStateController.isDozing() || mDocked;
+ boolean onAodOrDocked = mDozing || mDocked;
boolean invisible = onAodOrDocked || mWakeAndUnlockRunning || mShowingLaunchAffordance;
boolean fingerprintOrBypass = mFingerprintUnlock
|| mKeyguardBypassController.getBypassEnabled();
@@ -569,21 +366,202 @@ public class LockscreenLockIconController {
invisible = true;
}
}
- return mLockIcon.updateIconVisibility(!invisible);
+ return mView.updateIconVisibility(!invisible);
}
private void updateClickability() {
- if (mAccessibilityController == null) {
+ if (mView == null) {
return;
}
boolean canLock = mKeyguardStateController.isMethodSecure()
&& mKeyguardStateController.canDismissLockScreen();
boolean clickToUnlock = mAccessibilityController.isAccessibilityEnabled();
- if (mLockIcon != null) {
- mLockIcon.setClickable(clickToUnlock);
- mLockIcon.setLongClickable(canLock && !clickToUnlock);
- mLockIcon.setFocusable(mAccessibilityController.isAccessibilityEnabled());
- }
+ mView.setClickable(clickToUnlock);
+ mView.setLongClickable(canLock && !clickToUnlock);
+ mView.setFocusable(mAccessibilityController.isAccessibilityEnabled());
}
+ private final StatusBarStateController.StateListener mSBStateListener =
+ new StatusBarStateController.StateListener() {
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ if (mDozing != isDozing) {
+ mDozing = isDozing;
+ update();
+ }
+ }
+
+ @Override
+ public void onDozeAmountChanged(float linear, float eased) {
+ if (mView != null) {
+ mView.setDozeAmount(eased);
+ }
+ }
+
+ @Override
+ public void onStateChanged(int newState) {
+ setStatusBarState(newState);
+ }
+ };
+
+ private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
+ private int mDensity;
+
+ @Override
+ public void onUiModeChanged() {
+ updateColor();
+ }
+
+ @Override
+ public void onOverlayChanged() {
+ updateColor();
+ }
+
+ @Override
+ public void onDensityOrFontScaleChanged() {
+ ViewGroup.LayoutParams lp = mView.getLayoutParams();
+ if (lp == null) {
+ return;
+ }
+ lp.width = mView.getResources().getDimensionPixelSize(R.dimen.keyguard_lock_width);
+ lp.height = mView.getResources().getDimensionPixelSize(
+ R.dimen.keyguard_lock_height);
+ mView.setLayoutParams(lp);
+ update(true /* force */);
+ }
+
+ @Override
+ public void onLocaleListChanged() {
+ mView.setContentDescription(
+ mView.getResources().getText(R.string.accessibility_unlock_button));
+ update(true /* force */);
+ }
+
+ @Override
+ public void onConfigChanged(Configuration newConfig) {
+ final int density = newConfig.densityDpi;
+ if (density != mDensity) {
+ mDensity = density;
+ update();
+ }
+ }
+ };
+
+ private final WakeUpListener mWakeUpListener = new WakeUpListener() {
+ @Override
+ public void onPulseExpansionChanged(boolean expandingChanged) {
+ }
+
+ @Override
+ public void onFullyHiddenChanged(boolean isFullyHidden) {
+ if (mKeyguardBypassController.getBypassEnabled()) {
+ boolean changed = updateIconVisibility();
+ if (changed) {
+ update();
+ }
+ }
+ }
+ };
+
+ private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onSimStateChanged(int subId, int slotId, int simState) {
+ mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
+ update();
+ }
+
+ @Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ update();
+ }
+
+ @Override
+ public void onBiometricRunningStateChanged(boolean running,
+ BiometricSourceType biometricSourceType) {
+ update();
+ }
+
+ @Override
+ public void onStrongAuthStateChanged(int userId) {
+ update();
+ }
+ };
+
+ private final DockManager.DockEventListener mDockEventListener =
+ event -> {
+ boolean docked =
+ event == DockManager.STATE_DOCKED || event == DockManager.STATE_DOCKED_HIDE;
+ if (docked != mDocked) {
+ mDocked = docked;
+ update();
+ }
+ };
+
+ private final KeyguardStateController.Callback mKeyguardMonitorCallback =
+ new KeyguardStateController.Callback() {
+ @Override
+ public void onKeyguardShowingChanged() {
+ boolean force = false;
+ boolean wasShowing = mKeyguardShowing;
+ mKeyguardShowing = mKeyguardStateController.isShowing();
+ if (!wasShowing && mKeyguardShowing && mBlockUpdates) {
+ mBlockUpdates = false;
+ force = true;
+ }
+ if (!wasShowing && mKeyguardShowing) {
+ setBouncerHideAmount(KeyguardBouncer.EXPANSION_HIDDEN);
+ mKeyguardJustShown = true;
+ }
+ update(force);
+ }
+
+ @Override
+ public void onKeyguardFadingAwayChanged() {
+ if (!mKeyguardStateController.isKeyguardFadingAway()) {
+ if (mBlockUpdates) {
+ mBlockUpdates = false;
+ update(true /* force */);
+ }
+ }
+ }
+
+ @Override
+ public void onUnlockedChanged() {
+ update();
+ }
+ };
+
+ private final View.AccessibilityDelegate mAccessibilityDelegate =
+ new View.AccessibilityDelegate() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host,
+ AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ boolean fingerprintRunning =
+ mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
+ // Only checking if unlocking with Biometric is allowed (no matter strong or
+ // non-strong as long as primary auth, i.e. PIN/pattern/password, is not
+ // required), so it's ok to pass true for isStrongBiometric to
+ // isUnlockingWithBiometricAllowed() to bypass the check of whether non-strong
+ // biometric is allowed
+ boolean unlockingAllowed = mKeyguardUpdateMonitor
+ .isUnlockingWithBiometricAllowed(true /* isStrongBiometric */);
+ if (fingerprintRunning && unlockingAllowed) {
+ AccessibilityNodeInfo.AccessibilityAction unlock =
+ new AccessibilityNodeInfo.AccessibilityAction(
+ AccessibilityNodeInfo.ACTION_CLICK,
+ mResources.getString(
+ R.string.accessibility_unlock_without_fingerprint));
+ info.addAction(unlock);
+ info.setHintText(mResources.getString(
+ R.string.accessibility_waiting_for_fingerprint));
+ } else if (getState() == STATE_SCANNING_FACE) {
+ //Avoid 'button' to be spoken for scanning face
+ info.setClassName(LockIcon.class.getName());
+ info.setContentDescription(mResources.getString(
+ R.string.accessibility_scanning_face));
+ }
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index b24d0e7762ad..a5284f1421a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -910,7 +910,7 @@ public class NotificationPanelViewController extends PanelViewController {
clockPreferredY, hasCustomClock(),
hasVisibleNotifications, mInterpolatedDarkAmount, mEmptyDragAmount,
bypassEnabled, getUnlockedStackScrollerPadding(),
- mUpdateMonitor.shouldShowLockIcon(),
+ mUpdateMonitor.canShowLockIcon(),
getQsExpansionFraction(),
mDisplayCutoutTopInset);
mClockPositionAlgorithm.run(mClockPositionResult);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 19c0b6dc193a..e39065b6cc04 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -48,6 +48,7 @@ import com.android.systemui.DejankUtils;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.statusbar.BlurUtils;
import com.android.systemui.statusbar.FeatureFlags;
@@ -65,6 +66,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
import javax.inject.Inject;
@@ -150,6 +152,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
private final AlarmTimeout mTimeTicker;
private final KeyguardVisibilityCallback mKeyguardVisibilityCallback;
private final Handler mHandler;
+ private final Executor mMainExecutor;
private final BlurUtils mBlurUtils;
private GradientColors mColors;
@@ -214,8 +217,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
DelayedWakeLock.Builder delayedWakeLockBuilder, Handler handler,
KeyguardUpdateMonitor keyguardUpdateMonitor, DockManager dockManager,
BlurUtils blurUtils, ConfigurationController configurationController,
- FeatureFlags featureFlags) {
-
+ FeatureFlags featureFlags, @Main Executor mainExecutor) {
mScrimStateListener = lightBarController::setScrimState;
mDefaultScrimAlpha = featureFlags.isShadeOpaque() ? BUSY_SCRIM_ALPHA : GAR_SCRIM_ALPHA;
ScrimState.BUBBLE_EXPANDED.setBubbleAlpha(featureFlags.isShadeOpaque()
@@ -228,6 +230,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mKeyguardVisibilityCallback = new KeyguardVisibilityCallback();
mHandler = handler;
+ mMainExecutor = mainExecutor;
mTimeTicker = new AlarmTimeout(alarmManager, this::onHideWallpaperTimeout,
"hide_aod_wallpaper", mHandler);
mWakeLock = delayedWakeLockBuilder.setHandler(mHandler).setTag("Scrims").build();
@@ -273,7 +276,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
updateThemeColors();
if (mScrimBehindChangeRunnable != null) {
- mScrimBehind.setChangeRunnable(mScrimBehindChangeRunnable);
+ mScrimBehind.setChangeRunnable(mScrimBehindChangeRunnable, mMainExecutor);
mScrimBehindChangeRunnable = null;
}
@@ -1022,7 +1025,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
if (mScrimBehind == null) {
mScrimBehindChangeRunnable = changeRunnable;
} else {
- mScrimBehind.setChangeRunnable(changeRunnable);
+ mScrimBehind.setChangeRunnable(changeRunnable, mMainExecutor);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index b20c45780183..4a3d8d67e85d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -26,6 +26,7 @@ import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.InsetsState.containsType;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS;
import static androidx.lifecycle.Lifecycle.State.RESUMED;
@@ -367,7 +368,6 @@ public class StatusBar extends SystemUI implements DemoMode,
protected NotificationShadeWindowController mNotificationShadeWindowController;
protected StatusBarWindowController mStatusBarWindowController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- private final LockscreenLockIconController mLockscreenLockIconController;
@VisibleForTesting
DozeServiceHost mDozeServiceHost;
private boolean mWakeUpComingFromTouch;
@@ -414,6 +414,7 @@ public class StatusBar extends SystemUI implements DemoMode,
// expanded notifications
// the sliding/resizing panel within the notification window
protected NotificationPanelViewController mNotificationPanelViewController;
+ protected LockscreenLockIconController mLockscreenLockIconController;
// settings
private QSPanelController mQSPanelController;
@@ -724,7 +725,6 @@ public class StatusBar extends SystemUI implements DemoMode,
Lazy<AssistManager> assistManagerLazy,
ConfigurationController configurationController,
NotificationShadeWindowController notificationShadeWindowController,
- LockscreenLockIconController lockscreenLockIconController,
DozeParameters dozeParameters,
ScrimController scrimController,
@Nullable KeyguardLiftController keyguardLiftController,
@@ -806,7 +806,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mAssistManagerLazy = assistManagerLazy;
mConfigurationController = configurationController;
mNotificationShadeWindowController = notificationShadeWindowController;
- mLockscreenLockIconController = lockscreenLockIconController;
mDozeServiceHost = dozeServiceHost;
mPowerManager = powerManager;
mDozeParameters = dozeParameters;
@@ -841,8 +840,10 @@ public class StatusBar extends SystemUI implements DemoMode,
mBubbleExpandListener =
(isExpanding, key) -> {
- mNotificationsController.requestNotificationUpdate("onBubbleExpandChanged");
- updateScrimController();
+ mContext.getMainExecutor().execute(() -> {
+ mNotificationsController.requestNotificationUpdate("onBubbleExpandChanged");
+ updateScrimController();
+ });
};
mActivityIntentHelper = new ActivityIntentHelper(mContext);
@@ -1170,9 +1171,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mScrimController.setScrimVisibleListener(scrimsVisible -> {
mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
- if (mNotificationShadeWindowView != null) {
- mLockscreenLockIconController.onScrimVisibilityChanged(scrimsVisible);
- }
+ mLockscreenLockIconController.onScrimVisibilityChanged(scrimsVisible);
});
mScrimController.attachViews(scrimBehind, scrimInFront, scrimForBubble);
@@ -1205,9 +1204,6 @@ public class StatusBar extends SystemUI implements DemoMode,
createUserSwitcher();
}
- mNotificationPanelViewController.setLaunchAffordanceListener(
- mLockscreenLockIconController::onShowingLaunchAffordanceChanged);
-
// Set up the quick settings tile panel
final View container = mNotificationShadeWindowView.findViewById(R.id.qs_frame);
if (container != null) {
@@ -1487,6 +1483,11 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarWindowController = statusBarComponent.getStatusBarWindowController();
mPhoneStatusBarWindow = mSuperStatusBarViewFactory.getStatusBarWindowView();
mNotificationPanelViewController = statusBarComponent.getNotificationPanelViewController();
+ mLockscreenLockIconController = statusBarComponent.getLockscreenLockIconController();
+ mLockscreenLockIconController.init();
+
+ mNotificationPanelViewController.setLaunchAffordanceListener(
+ mLockscreenLockIconController::onShowingLaunchAffordanceChanged);
}
protected void startKeyguard() {
@@ -2428,6 +2429,8 @@ public class StatusBar extends SystemUI implements DemoMode,
return MODE_LIGHTS_OUT_TRANSPARENT;
} else if ((appearance & APPEARANCE_OPAQUE_STATUS_BARS) != 0) {
return MODE_OPAQUE;
+ } else if ((appearance & APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS) != 0) {
+ return MODE_SEMI_TRANSPARENT;
} else {
return MODE_TRANSPARENT;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index 5f90077640ec..f6165f666c89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -316,11 +316,23 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
mIconController.removeAllIconsForSlot(mSlotMobile);
mMobileStates.clear();
+ List<NoCallingIconState> noCallingStates = new ArrayList<NoCallingIconState>();
+ noCallingStates.addAll(mNoCallingStates);
mNoCallingStates.clear();
final int n = subs.size();
for (int i = 0; i < n; i++) {
mMobileStates.add(new MobileIconState(subs.get(i).getSubscriptionId()));
- mNoCallingStates.add(new NoCallingIconState(subs.get(i).getSubscriptionId()));
+ boolean isNewSub = true;
+ for (NoCallingIconState state : noCallingStates) {
+ if (state.subId == subs.get(i).getSubscriptionId()) {
+ mNoCallingStates.add(state);
+ isNewSub = false;
+ break;
+ }
+ }
+ if (isNewSub) {
+ mNoCallingStates.add(new NoCallingIconState(subs.get(i).getSubscriptionId()));
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
index 802da3e8c21c..ecd9613f84b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import com.android.systemui.statusbar.phone.LockscreenLockIconController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController;
@@ -73,4 +74,9 @@ public interface StatusBarComponent {
@StatusBarScope
NotificationPanelViewController getNotificationPanelViewController();
+ /**
+ * Creates a LockscreenLockIconController.
+ */
+ @StatusBarScope
+ LockscreenLockIconController getLockscreenLockIconController();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 26e19596b577..9e9533d0e199 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -77,7 +77,6 @@ import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LightsOutNotifController;
-import com.android.systemui.statusbar.phone.LockscreenLockIconController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
@@ -167,7 +166,6 @@ public interface StatusBarPhoneModule {
Lazy<AssistManager> assistManagerLazy,
ConfigurationController configurationController,
NotificationShadeWindowController notificationShadeWindowController,
- LockscreenLockIconController lockscreenLockIconController,
DozeParameters dozeParameters,
ScrimController scrimController,
@Nullable KeyguardLiftController keyguardLiftController,
@@ -248,7 +246,6 @@ public interface StatusBarPhoneModule {
assistManagerLazy,
configurationController,
notificationShadeWindowController,
- lockscreenLockIconController,
dozeParameters,
scrimController,
keyguardLiftController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 37d8c9ae2958..781abe6cef3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -16,6 +16,10 @@
package com.android.systemui.statusbar.phone.dagger;
+import android.annotation.Nullable;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
@@ -32,4 +36,12 @@ public abstract class StatusBarViewModule {
return notificationShadeWindowView.getNotificationPanelView();
}
+ /** */
+ @Provides
+ @StatusBarComponent.StatusBarScope
+ @Nullable
+ public static LockIcon getLockIcon(
+ NotificationShadeWindowView notificationShadeWindowView) {
+ return notificationShadeWindowView.findViewById(R.id.lock_icon);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index bf823b4b22b8..6e7aed064159 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -38,6 +38,7 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.res.Configuration;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.service.notification.NotificationListenerService.RankingMap;
@@ -83,10 +84,14 @@ import com.android.wm.shell.bubbles.Bubbles;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
import java.util.function.IntConsumer;
+import java.util.function.Supplier;
/**
* The SysUi side bubbles manager which communicate with other SysUi components.
@@ -106,8 +111,9 @@ public class BubblesManager implements Dumpable {
private final NotificationGroupManagerLegacy mNotificationGroupManager;
private final NotificationEntryManager mNotificationEntryManager;
private final NotifPipeline mNotifPipeline;
+ private final Executor mSysuiMainExecutor;
- private final ScrimView mBubbleScrim;
+ private ScrimView mBubbleScrim;
private final Bubbles.SysuiProxy mSysuiProxy;
// TODO (b/145659174): allow for multiple callbacks to support the "shadow" new notif pipeline
private final List<NotifCallback> mCallbacks = new ArrayList<>();
@@ -133,14 +139,15 @@ public class BubblesManager implements Dumpable {
NotifPipeline notifPipeline,
SysUiState sysUiState,
FeatureFlags featureFlags,
- DumpManager dumpManager) {
+ DumpManager dumpManager,
+ Executor sysuiMainExecutor) {
if (bubblesOptional.isPresent()) {
return new BubblesManager(context, bubblesOptional.get(),
notificationShadeWindowController, statusBarStateController, shadeController,
configurationController, statusBarService, notificationManager,
interruptionStateProvider, zenModeController, notifUserManager,
groupManager, entryManager, notifPipeline, sysUiState, featureFlags,
- dumpManager);
+ dumpManager, sysuiMainExecutor);
} else {
return null;
}
@@ -163,7 +170,8 @@ public class BubblesManager implements Dumpable {
NotifPipeline notifPipeline,
SysUiState sysUiState,
FeatureFlags featureFlags,
- DumpManager dumpManager) {
+ DumpManager dumpManager,
+ Executor sysuiMainExecutor) {
mContext = context;
mBubbles = bubbles;
mNotificationShadeWindowController = notificationShadeWindowController;
@@ -173,6 +181,7 @@ public class BubblesManager implements Dumpable {
mNotificationGroupManager = groupManager;
mNotificationEntryManager = entryManager;
mNotifPipeline = notifPipeline;
+ mSysuiMainExecutor = sysuiMainExecutor;
mBarService = statusBarService == null
? IStatusBarService.Stub.asInterface(
@@ -181,7 +190,9 @@ public class BubblesManager implements Dumpable {
mBubbleScrim = new ScrimView(mContext);
mBubbleScrim.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
- mBubbles.setBubbleScrim(mBubbleScrim);
+ mBubbles.setBubbleScrim(mBubbleScrim, (executor, looper) -> {
+ mBubbleScrim.setExecutor(executor, looper);
+ });
if (featureFlags.isNewNotifPipelineRenderingEnabled()) {
setupNotifPipeline();
@@ -237,128 +248,177 @@ public class BubblesManager implements Dumpable {
});
mSysuiProxy = new Bubbles.SysuiProxy() {
+ private <T> T executeBlockingForResult(Supplier<T> runnable, Executor executor,
+ Class clazz) {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ return runnable.get();
+ }
+ final T[] result = (T[]) Array.newInstance(clazz, 1);
+ final CountDownLatch latch = new CountDownLatch(1);
+ executor.execute(() -> {
+ result[0] = runnable.get();
+ latch.countDown();
+ });
+ try {
+ latch.await();
+ return result[0];
+ } catch (InterruptedException e) {
+ return null;
+ }
+ }
+
@Override
@Nullable
public BubbleEntry getPendingOrActiveEntry(String key) {
- NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(key);
- return entry == null ? null : notifToBubbleEntry(entry);
+ return executeBlockingForResult(() -> {
+ NotificationEntry entry =
+ mNotificationEntryManager.getPendingOrActiveNotif(key);
+ return entry == null ? null : notifToBubbleEntry(entry);
+ }, sysuiMainExecutor, BubbleEntry.class);
}
@Override
public List<BubbleEntry> getShouldRestoredEntries(ArraySet<String> savedBubbleKeys) {
- List<BubbleEntry> result = new ArrayList<>();
- List<NotificationEntry> activeEntries =
- mNotificationEntryManager.getActiveNotificationsForCurrentUser();
- for (int i = 0; i < activeEntries.size(); i++) {
- NotificationEntry entry = activeEntries.get(i);
- if (savedBubbleKeys.contains(entry.getKey())
- && mNotificationInterruptStateProvider.shouldBubbleUp(entry)
- && entry.isBubble()) {
- result.add(notifToBubbleEntry(entry));
+ return executeBlockingForResult(() -> {
+ List<BubbleEntry> result = new ArrayList<>();
+ List<NotificationEntry> activeEntries =
+ mNotificationEntryManager.getActiveNotificationsForCurrentUser();
+ for (int i = 0; i < activeEntries.size(); i++) {
+ NotificationEntry entry = activeEntries.get(i);
+ if (savedBubbleKeys.contains(entry.getKey())
+ && mNotificationInterruptStateProvider.shouldBubbleUp(entry)
+ && entry.isBubble()) {
+ result.add(notifToBubbleEntry(entry));
+ }
}
- }
- return result;
+ return result;
+ }, sysuiMainExecutor, List.class);
}
@Override
public boolean isNotificationShadeExpand() {
- return mNotificationShadeWindowController.getPanelExpanded();
+ return executeBlockingForResult(() -> {
+ return mNotificationShadeWindowController.getPanelExpanded();
+ }, sysuiMainExecutor, Boolean.class);
}
@Override
public boolean shouldBubbleUp(String key) {
- final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
- key);
- if (entry != null) {
- return mNotificationInterruptStateProvider.shouldBubbleUp(entry);
- }
- return false;
+ return executeBlockingForResult(() -> {
+ final NotificationEntry entry =
+ mNotificationEntryManager.getPendingOrActiveNotif(key);
+ if (entry != null) {
+ return mNotificationInterruptStateProvider.shouldBubbleUp(entry);
+ }
+ return false;
+ }, sysuiMainExecutor, Boolean.class);
}
@Override
public void setNotificationInterruption(String key) {
- final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
- key);
- if (entry != null && entry.getImportance() >= NotificationManager.IMPORTANCE_HIGH) {
- entry.setInterruption();
- }
+ sysuiMainExecutor.execute(() -> {
+ final NotificationEntry entry =
+ mNotificationEntryManager.getPendingOrActiveNotif(key);
+ if (entry != null
+ && entry.getImportance() >= NotificationManager.IMPORTANCE_HIGH) {
+ entry.setInterruption();
+ }
+ });
}
@Override
public void requestNotificationShadeTopUi(boolean requestTopUi, String componentTag) {
- mNotificationShadeWindowController.setRequestTopUi(requestTopUi, componentTag);
+ sysuiMainExecutor.execute(() -> {
+ mNotificationShadeWindowController.setRequestTopUi(requestTopUi, componentTag);
+ });
}
@Override
public void notifyRemoveNotification(String key, int reason) {
- final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
- key);
- if (entry != null) {
- for (NotifCallback cb : mCallbacks) {
- cb.removeNotification(entry, getDismissedByUserStats(entry, true), reason);
+ sysuiMainExecutor.execute(() -> {
+ final NotificationEntry entry =
+ mNotificationEntryManager.getPendingOrActiveNotif(key);
+ if (entry != null) {
+ for (NotifCallback cb : mCallbacks) {
+ cb.removeNotification(entry, getDismissedByUserStats(entry, true),
+ reason);
+ }
}
- }
+ });
}
@Override
public void notifyInvalidateNotifications(String reason) {
- for (NotifCallback cb : mCallbacks) {
- cb.invalidateNotifications(reason);
- }
+ sysuiMainExecutor.execute(() -> {
+ for (NotifCallback cb : mCallbacks) {
+ cb.invalidateNotifications(reason);
+ }
+ });
}
@Override
public void notifyMaybeCancelSummary(String key) {
- final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
- key);
- if (entry != null) {
- for (NotifCallback cb : mCallbacks) {
- cb.maybeCancelSummary(entry);
+ sysuiMainExecutor.execute(() -> {
+ final NotificationEntry entry =
+ mNotificationEntryManager.getPendingOrActiveNotif(key);
+ if (entry != null) {
+ for (NotifCallback cb : mCallbacks) {
+ cb.maybeCancelSummary(entry);
+ }
}
- }
+ });
}
@Override
public void removeNotificationEntry(String key) {
- final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
- key);
- if (entry != null) {
- mNotificationGroupManager.onEntryRemoved(entry);
- }
+ sysuiMainExecutor.execute(() -> {
+ final NotificationEntry entry =
+ mNotificationEntryManager.getPendingOrActiveNotif(key);
+ if (entry != null) {
+ mNotificationGroupManager.onEntryRemoved(entry);
+ }
+ });
}
@Override
public void updateNotificationBubbleButton(String key) {
- final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
- key);
- if (entry != null && entry.getRow() != null) {
- entry.getRow().updateBubbleButton();
- }
+ sysuiMainExecutor.execute(() -> {
+ final NotificationEntry entry =
+ mNotificationEntryManager.getPendingOrActiveNotif(key);
+ if (entry != null && entry.getRow() != null) {
+ entry.getRow().updateBubbleButton();
+ }
+ });
}
@Override
public void updateNotificationSuppression(String key) {
- final NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif(
- key);
- if (entry != null) {
- mNotificationGroupManager.updateSuppression(entry);
- }
+ sysuiMainExecutor.execute(() -> {
+ final NotificationEntry entry =
+ mNotificationEntryManager.getPendingOrActiveNotif(key);
+ if (entry != null) {
+ mNotificationGroupManager.updateSuppression(entry);
+ }
+ });
}
@Override
public void onStackExpandChanged(boolean shouldExpand) {
- sysUiState
- .setFlag(QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED, shouldExpand)
- .commitUpdate(mContext.getDisplayId());
+ sysuiMainExecutor.execute(() -> {
+ sysUiState.setFlag(QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED, shouldExpand)
+ .commitUpdate(mContext.getDisplayId());
+ });
}
@Override
public void onUnbubbleConversation(String key) {
- final NotificationEntry entry =
- mNotificationEntryManager.getPendingOrActiveNotif(key);
- if (entry != null) {
- onUserChangedBubble(entry, false /* shouldBubble */);
- }
+ sysuiMainExecutor.execute(() -> {
+ final NotificationEntry entry =
+ mNotificationEntryManager.getPendingOrActiveNotif(key);
+ if (entry != null) {
+ onUserChangedBubble(entry, false /* shouldBubble */);
+ }
+ });
}
};
mBubbles.setSysuiProxy(mSysuiProxy);
@@ -424,9 +484,8 @@ public class BubblesManager implements Dumpable {
final String groupKey = group.summary != null
? group.summary.getSbn().getGroupKey()
: null;
- if (!suppressed && groupKey != null
- && mBubbles.isSummarySuppressed(groupKey)) {
- mBubbles.removeSuppressedSummary(groupKey);
+ if (!suppressed && groupKey != null) {
+ mBubbles.removeSuppressedSummaryIfNecessary(groupKey, null, null);
}
}
});
@@ -449,19 +508,16 @@ public class BubblesManager implements Dumpable {
// Check if removed bubble has an associated suppressed group summary that needs
// to be removed now.
final String groupKey = entry.getSbn().getGroupKey();
- if (mBubbles.isSummarySuppressed(groupKey)) {
- mBubbles.removeSuppressedSummary(groupKey);
-
+ mBubbles.removeSuppressedSummaryIfNecessary(groupKey, (summaryKey) -> {
final NotificationEntry summary =
- mNotificationEntryManager.getActiveNotificationUnfiltered(
- mBubbles.getSummaryKey(groupKey));
+ mNotificationEntryManager.getActiveNotificationUnfiltered(summaryKey);
if (summary != null) {
mNotificationEntryManager.performRemoveNotification(
summary.getSbn(),
getDismissedByUserStats(summary, false),
UNDEFINED_DISMISS_REASON);
}
- }
+ }, mSysuiMainExecutor);
// Check if we still need to remove the summary from NoManGroup because the summary
// may not be in the mBubbleData.mSuppressedGroupKeys list and removed above.
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
index 103e6bb08ed4..c2e4e149f8e0 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -331,6 +331,7 @@ public abstract class WMShellBaseModule {
@BindsOptionalOf
abstract AppPairs optionalAppPairs();
+ // Note: Handler needed for LauncherApps.register
@WMSingleton
@Provides
static Optional<Bubbles> provideBubbles(Context context,
@@ -341,11 +342,12 @@ public abstract class WMShellBaseModule {
LauncherApps launcherApps,
UiEventLogger uiEventLogger,
ShellTaskOrganizer organizer,
- @ShellMainThread ShellExecutor mainExecutor) {
+ @ShellMainThread ShellExecutor mainExecutor,
+ @ShellMainThread Handler mainHandler) {
return Optional.of(BubbleController.create(context, null /* synchronizer */,
floatingContentCoordinator, statusBarService, windowManager,
windowManagerShellWrapper, launcherApps, uiEventLogger, organizer,
- mainExecutor));
+ mainExecutor, mainHandler));
}
// Needs the shell main handler for ContentObserver callbacks
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index dd145e419321..72dd4421e9ca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -27,7 +27,6 @@ import static org.mockito.Mockito.when;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.hardware.biometrics.SensorProperties;
-import android.hardware.display.DisplayManager;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -47,7 +46,6 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
@@ -86,15 +84,12 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Mock
private FingerprintManager mFingerprintManager;
@Mock
- private DisplayManager mDisplayManager;
- @Mock
private WindowManager mWindowManager;
@Mock
private StatusBarStateController mStatusBarStateController;
@Mock
private ScrimController mScrimController;
- private FakeSettings mSystemSettings;
private FakeExecutor mFgExecutor;
// Stuff for configuring mocks
@@ -109,7 +104,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Captor private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor;
private IUdfpsOverlayController mOverlayController;
@Captor private ArgumentCaptor<UdfpsView.OnTouchListener> mTouchListenerCaptor;
- @Captor private ArgumentCaptor<Runnable> mRunAfterShowingScrimAndDotCaptor;
+ @Captor private ArgumentCaptor<Runnable> mOnIlluminatedRunnableCaptor;
@Before
public void setUp() {
@@ -122,16 +117,13 @@ public class UdfpsControllerTest extends SysuiTestCase {
FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
true /* resetLockoutRequiresHardwareAuthToken */));
when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
- mSystemSettings = new FakeSettings();
mFgExecutor = new FakeExecutor(new FakeSystemClock());
mUdfpsController = new UdfpsController(
mContext,
mResources,
mLayoutInflater,
mFingerprintManager,
- mDisplayManager,
mWindowManager,
- mSystemSettings,
mStatusBarStateController,
mFgExecutor,
mScrimController);
@@ -183,7 +175,7 @@ public class UdfpsControllerTest extends SysuiTestCase {
@Test
public void fingerDown() throws RemoteException {
// Configure UdfpsView to accept the ACTION_DOWN event
- when(mUdfpsView.isShowScrimAndDot()).thenReturn(false);
+ when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
when(mUdfpsView.isValidTouch(anyFloat(), anyFloat(), anyFloat())).thenReturn(true);
// GIVEN that the overlay is showing
@@ -195,12 +187,11 @@ public class UdfpsControllerTest extends SysuiTestCase {
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, event);
event.recycle();
- // THEN the scrim and dot is shown
- verify(mUdfpsView).showScrimAndDot();
- // AND a runnable that passes the event to FingerprintManager is set on the view
- verify(mUdfpsView).setRunAfterShowingScrimAndDot(
- mRunAfterShowingScrimAndDotCaptor.capture());
- mRunAfterShowingScrimAndDotCaptor.getValue().run();
+ // THEN illumination begins
+ verify(mUdfpsView).startIllumination();
+ // AND onIlluminatedRunnable that notifies FingerprintManager is set
+ verify(mUdfpsView).setOnIlluminatedRunnable(mOnIlluminatedRunnableCaptor.capture());
+ mOnIlluminatedRunnableCaptor.getValue().run();
verify(mFingerprintManager).onPointerDown(eq(mUdfpsController.mSensorProps.sensorId), eq(0),
eq(0), eq(0f), eq(0f));
}
@@ -213,12 +204,11 @@ public class UdfpsControllerTest extends SysuiTestCase {
mFgExecutor.runAllReady();
// WHEN fingerprint is requested because of AOD interrupt
mUdfpsController.onAodInterrupt(0, 0, 2f, 3f);
- // THEN the scrim and dot is shown
- verify(mUdfpsView).showScrimAndDot();
- // AND a runnable that passes the event to FingerprintManager is set on the view
- verify(mUdfpsView).setRunAfterShowingScrimAndDot(
- mRunAfterShowingScrimAndDotCaptor.capture());
- mRunAfterShowingScrimAndDotCaptor.getValue().run();
+ // THEN illumination begins
+ verify(mUdfpsView).startIllumination();
+ // AND onIlluminatedRunnable that notifies FingerprintManager is set
+ verify(mUdfpsView).setOnIlluminatedRunnable(mOnIlluminatedRunnableCaptor.capture());
+ mOnIlluminatedRunnableCaptor.getValue().run();
verify(mFingerprintManager).onPointerDown(eq(mUdfpsController.mSensorProps.sensorId), eq(0),
eq(0), eq(3f) /* minor */, eq(2f) /* major */);
}
@@ -232,8 +222,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
mUdfpsController.onAodInterrupt(0, 0, 0f, 0f);
// WHEN it is cancelled
mUdfpsController.onCancelAodInterrupt();
- // THEN the scrim and dot is hidden
- verify(mUdfpsView).hideScrimAndDot();
+ // THEN the illumination is hidden
+ verify(mUdfpsView).stopIllumination();
}
@Test
@@ -246,8 +236,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
// WHEN it times out
mFgExecutor.advanceClockToNext();
mFgExecutor.runAllReady();
- // THEN the scrim and dot is hidden
- verify(mUdfpsView).hideScrimAndDot();
+ // THEN the illumination is hidden
+ verify(mUdfpsView).stopIllumination();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
index 9762ffffb02e..eb5dd4e6fef6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
@@ -72,7 +72,7 @@ class PrivacyDialogTest : SysuiTestCase() {
)
dialog = PrivacyDialog(context, list, starter)
dialog.show()
- dialog.requireViewById<View>(R.id.link).callOnClick()
+ dialog.requireViewById<View>(R.id.privacy_item).callOnClick()
verify(starter).invoke(PrivacyType.TYPE_MICROPHONE.permGroupName)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 23c093033ae0..bdde82289e86 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -88,7 +88,6 @@ public class DozeServiceHostTest extends SysuiTestCase {
@Mock private NotificationPanelViewController mNotificationPanel;
@Mock private View mAmbientIndicationContainer;
@Mock private BiometricUnlockController mBiometricUnlockController;
- @Mock private LockscreenLockIconController mLockscreenLockIconController;
@Mock private AuthController mAuthController;
@Before
@@ -100,7 +99,7 @@ public class DozeServiceHostTest extends SysuiTestCase {
mKeyguardViewMediator, () -> mAssistManager, mDozeScrimController,
mKeyguardUpdateMonitor, mPulseExpansionHandler,
mNotificationShadeWindowController, mNotificationWakeUpCoordinator,
- mLockscreenLockIconController, mAuthController, mNotificationIconAreaController);
+ mAuthController, mNotificationIconAreaController);
mDozeServiceHost.initialize(
mStatusBar,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java
index 95a35050c09e..60af16acbb7e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LockscreenIconControllerTest.java
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.phone;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -30,12 +29,12 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -45,6 +44,7 @@ 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.MockitoAnnotations;
@@ -64,7 +64,7 @@ public class LockscreenIconControllerTest extends SysuiTestCase {
@Mock
private KeyguardIndicationController mKeyguardIndicationController;
@Mock
- private LockIcon mLockIcon; // TODO: make this not a mock once inject is removed.
+ private LockIcon mLockIcon;
@Mock
private StatusBarStateController mStatusBarStateController;
@Mock
@@ -81,34 +81,36 @@ public class LockscreenIconControllerTest extends SysuiTestCase {
private Resources mResources;
@Mock
private HeadsUpManagerPhone mHeadsUpManagerPhone;
- @Mock
- private KeyguardSecurityModel mKeyguardSecurityModel;
private LockscreenLockIconController mLockIconController;
+
+ @Captor ArgumentCaptor<OnAttachStateChangeListener> mOnAttachStateChangeCaptor;
+ @Captor ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerCaptor;
+
private OnAttachStateChangeListener mOnAttachStateChangeListener;
+ private StatusBarStateController.StateListener mStatusBarStateListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(mKeyguardUpdateMonitor.shouldShowLockIcon()).thenReturn(true);
+ when(mKeyguardUpdateMonitor.canShowLockIcon()).thenReturn(true);
when(mLockIcon.getContext()).thenReturn(mContext);
- mLockIconController = new LockscreenLockIconController(
+ mLockIconController = new LockscreenLockIconController(mLockIcon,
mLockscreenGestureLogger, mKeyguardUpdateMonitor, mLockPatternUtils,
mShadeController, mAccessibilityController, mKeyguardIndicationController,
mStatusBarStateController, mConfigurationController, mNotificationWakeUpCoordinator,
mKeyguardBypassController, mDockManager, mKeyguardStateController, mResources,
- mHeadsUpManagerPhone, mKeyguardSecurityModel);
+ mHeadsUpManagerPhone);
- ArgumentCaptor<OnAttachStateChangeListener> onAttachStateChangeListenerArgumentCaptor =
- ArgumentCaptor.forClass(OnAttachStateChangeListener.class);
+ when(mLockIcon.isAttachedToWindow()).thenReturn(true);
+ mLockIconController.init();
- doNothing().when(mLockIcon)
- .addOnAttachStateChangeListener(
- onAttachStateChangeListenerArgumentCaptor.capture());
- mLockIconController.attach(mLockIcon);
-
- mOnAttachStateChangeListener = onAttachStateChangeListenerArgumentCaptor.getValue();
+ verify(mLockIcon).addOnAttachStateChangeListener(
+ mOnAttachStateChangeCaptor.capture());
+ mOnAttachStateChangeListener = mOnAttachStateChangeCaptor.getValue();
+ verify(mStatusBarStateController).addCallback(mStateListenerCaptor.capture());
+ mStatusBarStateListener = mStateListenerCaptor.getValue();
}
@Test
@@ -133,23 +135,17 @@ public class LockscreenIconControllerTest extends SysuiTestCase {
@Test
public void testVisibility_Dozing() {
- ArgumentCaptor<StatusBarStateController.StateListener> sBStateListenerCaptor =
- ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
-
- mOnAttachStateChangeListener.onViewAttachedToWindow(mLockIcon);
- verify(mStatusBarStateController).addCallback(sBStateListenerCaptor.capture());
-
when(mStatusBarStateController.isDozing()).thenReturn(true);
- sBStateListenerCaptor.getValue().onDozingChanged(true);
+ mStatusBarStateListener.onDozingChanged(true);
verify(mLockIcon).updateIconVisibility(false);
}
@Test
public void testVisibility_doNotShowLockIcon() {
- when(mKeyguardUpdateMonitor.shouldShowLockIcon()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.canShowLockIcon()).thenReturn(false);
+ mStatusBarStateListener.onStateChanged(StatusBarState.KEYGUARD);
- mOnAttachStateChangeListener.onViewAttachedToWindow(mLockIcon);
verify(mLockIcon).setVisibility(View.GONE);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 3b2e0550b9e7..21368d6d5309 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -54,6 +54,8 @@ import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.util.wakelock.DelayedWakeLock;
import com.android.systemui.utils.os.FakeHandler;
@@ -220,7 +222,8 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController = new ScrimController(mLightBarController,
mDozeParamenters, mAlarmManager, mKeyguardStateController, mDelayedWakeLockBuilder,
new FakeHandler(mLooper.getLooper()), mKeyguardUpdateMonitor,
- mDockManager, mBlurUtils, mConfigurationController, mFeatureFlags);
+ mDockManager, mBlurUtils, mConfigurationController, mFeatureFlags,
+ new FakeExecutor(new FakeSystemClock()));
mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
mScrimController.attachViews(mScrimBehind, mScrimInFront, mScrimForBubble);
mScrimController.setAnimatorListener(mAnimatorListener);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 2c781bad10c2..cae488a561a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -386,7 +386,6 @@ public class StatusBarTest extends SysuiTestCase {
() -> mAssistManager,
configurationController,
mNotificationShadeWindowController,
- mLockscreenLockIconController,
mDozeParameters,
mScrimController,
mKeyguardLiftController,
@@ -436,6 +435,7 @@ public class StatusBarTest extends SysuiTestCase {
// initialized automatically.
mStatusBar.mNotificationShadeWindowView = mNotificationShadeWindowView;
mStatusBar.mNotificationPanelViewController = mNotificationPanelViewController;
+ mStatusBar.mLockscreenLockIconController = mLockscreenLockIconController;
mStatusBar.mDozeScrimController = mDozeScrimController;
mStatusBar.mPresenter = mNotificationPresenter;
mStatusBar.mKeyguardIndicationController = mKeyguardIndicationController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index da1f5d392872..f8b63835551f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -37,6 +37,7 @@ import static org.mockito.Mockito.when;
import android.app.Instrumentation;
import android.content.Intent;
import android.net.ConnectivityManager;
+import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
@@ -343,6 +344,8 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
setConnectivityCommon(networkType, validated, isConnected);
if (networkType == NetworkCapabilities.TRANSPORT_WIFI) {
if (isConnected) {
+ mNetworkCallback.onAvailable(mock(Network.class),
+ new NetworkCapabilities(mNetCapabilities), new LinkProperties(), false);
mNetworkCallback.onCapabilitiesChanged(
mock(Network.class), new NetworkCapabilities(mNetCapabilities));
} else {
@@ -357,6 +360,8 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
setConnectivityCommon(networkType, validated, isConnected);
if (networkType == NetworkCapabilities.TRANSPORT_CELLULAR) {
if (isConnected) {
+ mNetworkCallback.onAvailable(mock(Network.class),
+ new NetworkCapabilities(mNetCapabilities), new LinkProperties(), false);
mNetworkCallback.onCapabilitiesChanged(
mock(Network.class), new NetworkCapabilities(mNetCapabilities));
} else {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index ccc2eb328a04..76269dda8245 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -166,6 +166,7 @@ public class BubblesTest extends SysuiTestCase {
private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor;
private BubblesManager mBubblesManager;
+ // TODO(178618782): Move tests on the controller directly to the shell
private TestableBubbleController mBubbleController;
private NotificationShadeWindowControllerImpl mNotificationShadeWindowController;
private NotificationEntryListener mEntryListener;
@@ -221,6 +222,9 @@ public class BubblesTest extends SysuiTestCase {
mTestableLooper = TestableLooper.get(this);
+ // For the purposes of this test, just run everything synchronously
+ ShellExecutor syncExecutor = new SyncExecutor();
+
mContext.addMockSystemService(FaceManager.class, mFaceManager);
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
@@ -257,8 +261,9 @@ public class BubblesTest extends SysuiTestCase {
mSysUiStateBubblesExpanded =
(sysUiFlags & QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED) != 0);
+ // TODO: Fix
mPositioner = new TestableBubblePositioner(mContext, mWindowManager);
- mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner);
+ mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner, syncExecutor);
TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
@@ -273,7 +278,7 @@ public class BubblesTest extends SysuiTestCase {
);
when(mFeatureFlagsOldPipeline.isNewNotifPipelineRenderingEnabled()).thenReturn(false);
- when(mShellTaskOrganizer.getExecutor()).thenReturn(new FakeExecutor(new FakeSystemClock()));
+ when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor);
mBubbleController = new TestableBubbleController(
mContext,
mBubbleData,
@@ -286,12 +291,13 @@ public class BubblesTest extends SysuiTestCase {
mBubbleLogger,
mShellTaskOrganizer,
mPositioner,
- mock(ShellExecutor.class));
+ syncExecutor,
+ mock(Handler.class));
mBubbleController.setExpandListener(mBubbleExpandListener);
mBubblesManager = new BubblesManager(
mContext,
- mBubbleController,
+ mBubbleController.getImpl(),
mNotificationShadeWindowController,
mStatusBarStateController,
mShadeController,
@@ -306,7 +312,8 @@ public class BubblesTest extends SysuiTestCase {
mNotifPipeline,
mSysUiState,
mFeatureFlagsOldPipeline,
- mDumpManager);
+ mDumpManager,
+ syncExecutor);
// Get a reference to the BubbleController's entry listener
verify(mNotificationEntryManager, atLeastOnce())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
index 00f4e3a3f144..5340ff7e967c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
@@ -83,8 +83,6 @@ import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.ZenModeController;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.bubbles.BubbleData;
@@ -203,6 +201,9 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
mTestableLooper = TestableLooper.get(this);
+ // For the purposes of this test, just run everything synchronously
+ ShellExecutor syncExecutor = new SyncExecutor();
+
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
@@ -227,7 +228,7 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
mPositioner = new TestableBubblePositioner(mContext, mWindowManager);
- mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner);
+ mBubbleData = new BubbleData(mContext, mBubbleLogger, mPositioner, syncExecutor);
TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
@@ -241,7 +242,7 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
mock(Handler.class)
);
when(mFeatureFlagsNewPipeline.isNewNotifPipelineRenderingEnabled()).thenReturn(true);
- when(mShellTaskOrganizer.getExecutor()).thenReturn(new FakeExecutor(new FakeSystemClock()));
+ when(mShellTaskOrganizer.getExecutor()).thenReturn(syncExecutor);
mBubbleController = new TestableBubbleController(
mContext,
mBubbleData,
@@ -254,12 +255,13 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
mBubbleLogger,
mShellTaskOrganizer,
mPositioner,
- mock(ShellExecutor.class));
+ syncExecutor,
+ mock(Handler.class));
mBubbleController.setExpandListener(mBubbleExpandListener);
mBubblesManager = new BubblesManager(
mContext,
- mBubbleController,
+ mBubbleController.getImpl(),
mNotificationShadeWindowController,
mStatusBarStateController,
mShadeController,
@@ -274,7 +276,8 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
mNotifPipeline,
mSysUiState,
mFeatureFlagsNewPipeline,
- mDumpManager);
+ mDumpManager,
+ syncExecutor);
mBubblesManager.addNotifCallback(mNotifCallback);
// Get a reference to the BubbleController's entry listener
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/SyncExecutor.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/SyncExecutor.java
new file mode 100644
index 000000000000..d40eecffb29e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/SyncExecutor.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.wmshell;
+
+import com.android.wm.shell.common.ShellExecutor;
+
+/**
+ * And executor that just executes everything synchronously. To be removed once we move the
+ * tests of shell behavior over to the shell.
+ */
+public class SyncExecutor implements ShellExecutor {
+ @Override
+ public void execute(Runnable runnable) {
+ runnable.run();
+ }
+
+ @Override
+ public void executeDelayed(Runnable runnable, long delayMillis) {
+ runnable.run();
+ }
+
+ @Override
+ public void removeAllCallbacks() {
+ }
+
+ @Override
+ public void removeCallbacks(Runnable runnable) {
+ }
+
+ @Override
+ public boolean hasCallback(Runnable runnable) {
+ return false;
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
index 3f918e8b8633..cdf47b82561e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableBubbleController.java
@@ -49,10 +49,11 @@ public class TestableBubbleController extends BubbleController {
BubbleLogger bubbleLogger,
ShellTaskOrganizer shellTaskOrganizer,
BubblePositioner positioner,
- ShellExecutor shellMainExecutor) {
+ ShellExecutor shellMainExecutor,
+ Handler shellMainHandler) {
super(context, data, Runnable::run, floatingContentCoordinator, dataRepository,
statusBarService, windowManager, windowManagerShellWrapper, launcherApps,
- bubbleLogger, shellTaskOrganizer, positioner, shellMainExecutor);
+ bubbleLogger, shellTaskOrganizer, positioner, shellMainExecutor, shellMainHandler);
setInflateSynchronously(true);
}
}
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index ae024ff6d043..5dd271c9dbb1 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -260,6 +260,10 @@ message SystemMessage {
// Package: android
NOTE_ADB_WIFI_ACTIVE = 62;
+ // Notify the user a carrier suggestion is available to get IMSI exemption.
+ // Package: android
+ NOTE_CARRIER_SUGGESTION_AVAILABLE = 63;
+
// ADD_NEW_IDS_ABOVE_THIS_LINE
// Legacy IDs with arbitrary values appear below
// Legacy IDs existed as stable non-conflicting constants prior to the O release
diff --git a/services/Android.bp b/services/Android.bp
index f6bb72a46b87..61591c2c29bd 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -28,6 +28,7 @@ filegroup {
":services.profcollect-sources",
":services.restrictions-sources",
":services.searchui-sources",
+ ":services.smartspace-sources",
":services.speech-sources",
":services.startop.iorap-sources",
":services.systemcaptions-sources",
@@ -36,6 +37,7 @@ filegroup {
":services.usb-sources",
":services.voiceinteraction-sources",
":services.wifi-sources",
+ ":service-media-s-sources", // TODO (b/177640454)
":service-permission-sources",
":service-statsd-sources",
],
@@ -76,6 +78,7 @@ java_library {
"services.profcollect",
"services.restrictions",
"services.searchui",
+ "services.smartspace",
"services.speech",
"services.startop",
"services.systemcaptions",
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 554edc6d74bd..c091dfa384ca 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -216,8 +216,6 @@ import com.android.server.net.LockdownVpnTracker;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.utils.PriorityDump;
-import com.google.android.collect.Lists;
-
import libcore.io.IoUtils;
import java.io.FileDescriptor;
@@ -1329,31 +1327,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
return mNextNetworkRequestId++;
}
- private NetworkState getFilteredNetworkState(int networkType, int uid) {
- if (mLegacyTypeTracker.isTypeSupported(networkType)) {
- final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
- final NetworkState state;
- if (nai != null) {
- state = nai.getNetworkState();
- state.networkInfo.setType(networkType);
- } else {
- final NetworkInfo info = new NetworkInfo(networkType, 0,
- getNetworkTypeName(networkType), "");
- info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
- info.setIsAvailable(true);
- final NetworkCapabilities capabilities = new NetworkCapabilities();
- capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING,
- !info.isRoaming());
- state = new NetworkState(info, new LinkProperties(), capabilities,
- null, null, null);
- }
- filterNetworkStateForUid(state, uid, false);
- return state;
- } else {
- return NetworkState.EMPTY;
- }
- }
-
@VisibleForTesting
protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
if (network == null) {
@@ -1464,6 +1437,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
"%s %d(%d) on netId %d", action, nri.mUid, requestId, net.getNetId()));
}
+ private void filterNetworkInfo(@NonNull NetworkInfo networkInfo,
+ @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked) {
+ if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) {
+ networkInfo.setDetailedState(DetailedState.BLOCKED, null, null);
+ }
+ synchronized (mVpns) {
+ if (mLockdownTracker != null) {
+ mLockdownTracker.augmentNetworkInfo(networkInfo);
+ }
+ }
+ }
+
/**
* Apply any relevant filters to {@link NetworkState} for the given UID. For
* example, this may mark the network as {@link DetailedState#BLOCKED} based
@@ -1471,16 +1456,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
private void filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked) {
if (state == null || state.networkInfo == null || state.linkProperties == null) return;
-
- if (isNetworkWithCapabilitiesBlocked(state.networkCapabilities, uid,
- ignoreBlocked)) {
- state.networkInfo.setDetailedState(DetailedState.BLOCKED, null, null);
- }
- synchronized (mVpns) {
- if (mLockdownTracker != null) {
- mLockdownTracker.augmentNetworkInfo(state.networkInfo);
- }
- }
+ filterNetworkInfo(state.networkInfo, state.networkCapabilities, uid, ignoreBlocked);
}
/**
@@ -1545,6 +1521,27 @@ public class ConnectivityService extends IConnectivityManager.Stub
return state.networkInfo;
}
+ private NetworkInfo getFilteredNetworkInfo(int networkType, int uid) {
+ if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
+ return null;
+ }
+ final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ final NetworkInfo info;
+ final NetworkCapabilities nc;
+ if (nai != null) {
+ info = new NetworkInfo(nai.networkInfo);
+ info.setType(networkType);
+ nc = nai.networkCapabilities;
+ } else {
+ info = new NetworkInfo(networkType, 0, getNetworkTypeName(networkType), "");
+ info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
+ info.setIsAvailable(true);
+ nc = new NetworkCapabilities();
+ }
+ filterNetworkInfo(info, nc, uid, false);
+ return info;
+ }
+
@Override
public NetworkInfo getNetworkInfo(int networkType) {
enforceAccessPermission();
@@ -1559,8 +1556,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
return state.networkInfo;
}
}
- final NetworkState state = getFilteredNetworkState(networkType, uid);
- return state.networkInfo;
+ return getFilteredNetworkInfo(networkType, uid);
}
@Override
@@ -1579,7 +1575,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public NetworkInfo[] getAllNetworkInfo() {
enforceAccessPermission();
- final ArrayList<NetworkInfo> result = Lists.newArrayList();
+ final ArrayList<NetworkInfo> result = new ArrayList<>();
for (int networkType = 0; networkType <= ConnectivityManager.MAX_NETWORK_TYPE;
networkType++) {
NetworkInfo info = getNetworkInfo(networkType);
@@ -1593,10 +1589,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public Network getNetworkForType(int networkType) {
enforceAccessPermission();
+ if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
+ return null;
+ }
+ final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ if (nai == null) {
+ return null;
+ }
final int uid = mDeps.getCallingUid();
- NetworkState state = getFilteredNetworkState(networkType, uid);
- if (!isNetworkWithCapabilitiesBlocked(state.networkCapabilities, uid, false)) {
- return state.network;
+ if (!isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) {
+ return nai.network;
}
return null;
}
@@ -1847,7 +1849,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// This contains IMSI details, so make sure the caller is privileged.
NetworkStack.checkNetworkStackPermission(mContext);
- final ArrayList<NetworkState> result = Lists.newArrayList();
+ final ArrayList<NetworkState> result = new ArrayList<>();
for (Network network : getAllNetworks()) {
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai != null) {
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index 8b506bac4a85..41903fcd165f 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -372,10 +372,12 @@ public class PackageWatchdog {
* even from a previous boot.
*/
public void unregisterHealthObserver(PackageHealthObserver observer) {
- synchronized (mLock) {
- mAllObservers.remove(observer.getName());
- }
- syncState("unregistering observer: " + observer.getName());
+ mLongTaskHandler.post(() -> {
+ synchronized (mLock) {
+ mAllObservers.remove(observer.getName());
+ }
+ syncState("unregistering observer: " + observer.getName());
+ });
}
/**
@@ -982,7 +984,11 @@ public class PackageWatchdog {
if (!DeviceConfig.NAMESPACE_ROLLBACK.equals(properties.getNamespace())) {
return;
}
- updateConfigs();
+ try {
+ updateConfigs();
+ } catch (Exception ignore) {
+ Slog.w(TAG, "Failed to reload device config changes");
+ }
});
}
@@ -990,7 +996,8 @@ public class PackageWatchdog {
* Health check is enabled or disabled after reading the flags
* from DeviceConfig.
*/
- private void updateConfigs() {
+ @VisibleForTesting
+ void updateConfigs() {
synchronized (mLock) {
mTriggerFailureCount = DeviceConfig.getInt(
DeviceConfig.NAMESPACE_ROLLBACK,
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 0412f08d3ae3..7d6515600c2a 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -48,6 +48,7 @@ import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
@@ -482,14 +483,21 @@ class StorageManagerService extends IStorageManager.Stub
}
}
- private @Nullable VolumeInfo findStorageForUuid(String volumeUuid) {
+ private @Nullable VolumeInfo findStorageForUuidAsUser(String volumeUuid,
+ @UserIdInt int userId) {
final StorageManager storage = mContext.getSystemService(StorageManager.class);
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
- return storage.findVolumeById(VolumeInfo.ID_EMULATED_INTERNAL + ";" + 0);
+ return storage.findVolumeById(VolumeInfo.ID_EMULATED_INTERNAL + ";" + userId);
} else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
return storage.getPrimaryPhysicalVolume();
} else {
- return storage.findEmulatedForPrivate(storage.findVolumeByUuid(volumeUuid));
+ VolumeInfo info = storage.findVolumeByUuid(volumeUuid);
+ if (info == null) {
+ Slog.w(TAG, "findStorageForUuidAsUser cannot find volumeUuid:" + volumeUuid);
+ return null;
+ }
+ String emulatedUuid = info.getId().replace("private", "emulated") + ";" + userId;
+ return storage.findVolumeById(emulatedUuid);
}
}
@@ -2605,8 +2613,9 @@ class StorageManagerService extends IStorageManager.Stub
return;
} else {
- from = findStorageForUuid(mPrimaryStorageUuid);
- to = findStorageForUuid(volumeUuid);
+ int currentUserId = mCurrentUserId;
+ from = findStorageForUuidAsUser(mPrimaryStorageUuid, currentUserId);
+ to = findStorageForUuidAsUser(volumeUuid, currentUserId);
if (from == null) {
Slog.w(TAG, "Failing move due to missing from volume " + mPrimaryStorageUuid);
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index a08d066513c7..e96fd390f15a 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -32,6 +32,7 @@ import android.net.NetworkAgent;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkProvider;
+import android.net.NetworkStack;
import android.net.RouteInfo;
import android.net.StringNetworkSpecifier;
import android.net.TestNetworkInterface;
@@ -48,6 +49,7 @@ import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.NetdUtils;
import java.io.UncheckedIOException;
import java.net.Inet4Address;
@@ -317,10 +319,10 @@ class TestNetworkService extends ITestNetworkManager.Stub {
}
try {
- // This requires NETWORK_STACK privileges.
final long token = Binder.clearCallingIdentity();
try {
- mNMS.setInterfaceUp(iface);
+ NetworkStack.checkNetworkStackPermission(mContext);
+ NetdUtils.setInterfaceUp(mNetd, iface);
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index d63a6c3a0a6f..5b5043141315 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -111,7 +111,6 @@ public class Watchdog {
};
public static final List<String> HAL_INTERFACES_OF_INTEREST = Arrays.asList(
- "android.hardware.audio@2.0::IDevicesFactory",
"android.hardware.audio@4.0::IDevicesFactory",
"android.hardware.audio@5.0::IDevicesFactory",
"android.hardware.audio@6.0::IDevicesFactory",
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 02613cfe0771..6216fc00417a 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2815,12 +2815,24 @@ public final class ActiveServices {
r = smap.mServicesByIntent.get(filter);
if (DEBUG_SERVICE && r != null) Slog.v(TAG_SERVICE, "Retrieved by intent: " + r);
}
- if (r != null && (r.serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0
- && !callingPackage.equals(r.packageName)) {
- // If an external service is running within its own package, other packages
- // should not bind to that instance.
- r = null;
- if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Whoops, can't use existing external service");
+ if (r != null) {
+ // Compared to resolveService below, the ServiceRecord here is retrieved from
+ // ServiceMap so the package visibility doesn't apply to it. We need to filter it.
+ if (mAm.getPackageManagerInternal().filterAppAccess(r.packageName, callingUid,
+ userId)) {
+ Slog.w(TAG_SERVICE, "Unable to start service " + service + " U=" + userId
+ + ": not found");
+ return null;
+ }
+ if ((r.serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0
+ && !callingPackage.equals(r.packageName)) {
+ // If an external service is running within its own package, other packages
+ // should not bind to that instance.
+ r = null;
+ if (DEBUG_SERVICE) {
+ Slog.v(TAG_SERVICE, "Whoops, can't use existing external service");
+ }
+ }
}
if (r == null) {
try {
@@ -4217,6 +4229,7 @@ public final class ActiveServices {
Slog.w(TAG, "Forcing bringing down service: " + sr);
sr.isolatedProc = null;
mPendingServices.remove(i);
+ size = mPendingServices.size();
i--;
needOomAdj = true;
bringDownServiceLocked(sr, true);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f63b994307b0..c8f5f8e60187 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -236,6 +236,7 @@ import android.os.DropBoxManager;
import android.os.FactoryTest;
import android.os.FileUtils;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IDeviceIdentifiersPolicyService;
import android.os.IPermissionController;
@@ -316,6 +317,7 @@ import com.android.internal.os.IResultReceiver;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.TransferPipe;
import com.android.internal.os.Zygote;
+import com.android.internal.policy.AttributeCache;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
@@ -326,7 +328,6 @@ import com.android.internal.util.Preconditions;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.server.AlarmManagerInternal;
-import com.android.server.AttributeCache;
import com.android.server.DeviceIdleInternal;
import com.android.server.DisplayThread;
import com.android.server.IntentResolver;
@@ -2098,11 +2099,19 @@ public class ActivityManagerService extends IActivityManager.Stub
mEnableOffloadQueue = SystemProperties.getBoolean(
"persist.device_config.activity_manager_native_boot.offload_queue_enabled", false);
- mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
+ // Decouple broadcast-related timing operations from other OS activity by
+ // using a dedicated thread. Sharing this thread between queues is safe
+ // because we know the nature of the activity on it and can't stall
+ // unexpectedly.
+ HandlerThread broadcastThread = new HandlerThread("broadcast");
+ broadcastThread.start();
+ Handler broadcastHandler = broadcastThread.getThreadHandler();
+
+ mFgBroadcastQueue = new BroadcastQueue(this, broadcastHandler,
"foreground", foreConstants, false);
- mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
+ mBgBroadcastQueue = new BroadcastQueue(this, broadcastHandler,
"background", backConstants, true);
- mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler,
+ mOffloadBroadcastQueue = new BroadcastQueue(this, broadcastHandler,
"offload", offloadConstants, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
@@ -4500,7 +4509,6 @@ public class ActivityManagerService extends IActivityManager.Stub
String data, Bundle extras, boolean ordered,
boolean sticky, int sendingUser) {
synchronized (ActivityManagerService.this) {
- mOomAdjuster.mCachedAppOptimizer.compactAllSystem();
mAppProfiler.requestPssAllProcsLocked(
SystemClock.uptimeMillis(), true, false);
}
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 27a238dd33ea..c558b3d00400 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -741,10 +741,12 @@ public final class CachedAppOptimizer {
// This will ensure app will be out of the freezer for at least FREEZE_TIMEOUT_MS
void unfreezeTemporarily(ProcessRecord app) {
- synchronized (mAm) {
- if (app.frozen) {
- unfreezeAppLocked(app);
- freezeAppAsync(app);
+ if (mUseFreezer) {
+ synchronized (mAm) {
+ if (app.frozen) {
+ unfreezeAppLocked(app);
+ freezeAppAsync(app);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index a768532a9260..bbf927b1ee2d 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -4447,7 +4447,7 @@ public final class ProcessList {
}
app.getPkgList().forEachPackage(packageName -> {
- if (updateFrameworkRes && packagesToUpdate.contains(packageName)) {
+ if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
try {
final ApplicationInfo ai = AppGlobals.getPackageManager()
.getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
diff --git a/services/core/java/com/android/server/am/ProcessProfileRecord.java b/services/core/java/com/android/server/am/ProcessProfileRecord.java
index cf309f4c8e3d..9fd2bd798c04 100644
--- a/services/core/java/com/android/server/am/ProcessProfileRecord.java
+++ b/services/core/java/com/android/server/am/ProcessProfileRecord.java
@@ -623,6 +623,8 @@ final class ProcessProfileRecord {
DebugUtils.printSizeValue(pw, mLastCachedSwapPss * 1024);
pw.print(" lastRss=");
DebugUtils.printSizeValue(pw, mLastRss * 1024);
+ pw.println();
+ pw.print(prefix);
pw.print(" trimMemoryLevel=");
pw.println(mTrimMemoryLevel);
pw.println();
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index f7e87ef94939..a1adeaac52ca 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -643,7 +643,7 @@ class ProcessRecord implements WindowProcessListener {
}
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
- mProfile.onProcessActive(thread, tracker);
+ mProfile.onProcessActive(_thread, tracker);
thread = _thread;
mWindowProcessController.setThread(thread);
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index b2824846008c..1a4f20c7101e 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -57,6 +57,7 @@ import com.android.internal.util.WakeupMessage;
import com.android.server.ConnectivityService;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
@@ -1025,6 +1026,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
+ (networkAgentConfig.acceptUnvalidated ? " acceptUnvalidated" : "")
+ (networkAgentConfig.acceptPartialConnectivity ? " acceptPartialConnectivity" : "")
+ (clatd.isStarted() ? " clat{" + clatd + "} " : "")
+ + (declaredUnderlyingNetworks != null
+ ? " underlying{" + Arrays.toString(declaredUnderlyingNetworks) + "}" : "")
+ " lp{" + linkProperties + "}"
+ " nc{" + networkCapabilities + "}"
+ "}";
diff --git a/services/core/java/com/android/server/graphics/fonts/FontCrashDetector.java b/services/core/java/com/android/server/graphics/fonts/FontCrashDetector.java
new file mode 100644
index 000000000000..b082b25aea02
--- /dev/null
+++ b/services/core/java/com/android/server/graphics/fonts/FontCrashDetector.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 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.graphics.fonts;
+
+import android.annotation.NonNull;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * A class to detect font-related native crash.
+ *
+ * <p>If a fs-verity protected file is accessed through mmap and corrupted file block is detected,
+ * SIGBUG signal is generated and the process will crash. To find corrupted files and remove them,
+ * we use a marker file to detect crash.
+ * <ol>
+ * <li>Create a marker file before reading fs-verity protected font files.
+ * <li>Delete the marker file after reading font files successfully.
+ * <li>If the marker file is found in the next process startup, it means that the process
+ * crashed before. We will delete font files to prevent crash loop.
+ * </ol>
+ *
+ * <p>Example usage:
+ * <pre>
+ * FontCrashDetector detector = new FontCrashDetector(new File("/path/to/marker_file"));
+ * if (detector.hasCrashed()) {
+ * // Do cleanup
+ * }
+ * try (FontCrashDetector.MonitoredBlock b = detector.start()) {
+ * // Read files
+ * }
+ * </pre>
+ *
+ * <p>This class DOES NOT detect Java exceptions. If a Java exception is thrown while monitoring
+ * crash, the marker file will be deleted. Creating and deleting marker files are not lightweight.
+ * Please use this class sparingly with caution.
+ */
+/* package */ final class FontCrashDetector {
+
+ private static final String TAG = "FontCrashDetector";
+
+ @NonNull
+ private final File mMarkerFile;
+
+ /* package */ FontCrashDetector(@NonNull File markerFile) {
+ mMarkerFile = markerFile;
+ }
+
+ /* package */ boolean hasCrashed() {
+ return mMarkerFile.exists();
+ }
+
+ /* package */ void clear() {
+ if (!mMarkerFile.delete()) {
+ Slog.e(TAG, "Could not delete marker file: " + mMarkerFile);
+ }
+ }
+
+ /** Starts crash monitoring. */
+ /* package */ MonitoredBlock start() {
+ try {
+ mMarkerFile.createNewFile();
+ } catch (IOException e) {
+ Slog.e(TAG, "Could not create marker file: " + mMarkerFile, e);
+ }
+ return new MonitoredBlock();
+ }
+
+ /** A helper class to monitor crash with try-with-resources syntax. */
+ /* package */ class MonitoredBlock implements AutoCloseable {
+ /** Ends crash monitoring. */
+ @Override
+ public void close() {
+ clear();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
index 7461405c9a5f..8e5215b49f16 100644
--- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
@@ -64,6 +64,7 @@ public final class FontManagerService extends IFontManager.Stub {
private static final String TAG = "FontManagerService";
private static final String FONT_FILES_DIR = "/data/fonts/files";
+ private static final String CRASH_MARKER_FILE = "/data/fonts/config/crash.txt";
@Override
public FontConfig getFontConfig() throws RemoteException {
@@ -179,6 +180,13 @@ public final class FontManagerService extends IFontManager.Stub {
}
}
+ @NonNull
+ private final Context mContext;
+
+ @GuardedBy("FontManagerService.this")
+ @NonNull
+ private final FontCrashDetector mFontCrashDetector;
+
@Nullable
private final UpdatableFontDir mUpdatableFontDir;
@@ -188,7 +196,9 @@ public final class FontManagerService extends IFontManager.Stub {
private FontManagerService(Context context) {
mContext = context;
+ mFontCrashDetector = new FontCrashDetector(new File(CRASH_MARKER_FILE));
mUpdatableFontDir = createUpdatableFontDir();
+ initialize();
}
@Nullable
@@ -201,20 +211,35 @@ public final class FontManagerService extends IFontManager.Stub {
new OtfFontFileParser(), new FsverityUtilImpl());
}
-
- @NonNull
- private final Context mContext;
+ private void initialize() {
+ synchronized (FontManagerService.this) {
+ if (mUpdatableFontDir == null) {
+ mSerializedFontMap = buildNewSerializedFontMap();
+ return;
+ }
+ if (mFontCrashDetector.hasCrashed()) {
+ Slog.i(TAG, "Crash detected. Clearing font updates.");
+ try {
+ mUpdatableFontDir.clearUpdates();
+ } catch (SystemFontException e) {
+ Slog.e(TAG, "Failed to clear updates.", e);
+ }
+ mFontCrashDetector.clear();
+ }
+ try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) {
+ mUpdatableFontDir.loadFontFileMap();
+ mSerializedFontMap = buildNewSerializedFontMap();
+ }
+ }
+ }
@NonNull
public Context getContext() {
return mContext;
}
- @NonNull /* package */ SharedMemory getCurrentFontMap() {
+ @Nullable /* package */ SharedMemory getCurrentFontMap() {
synchronized (FontManagerService.this) {
- if (mSerializedFontMap == null) {
- mSerializedFontMap = buildNewSerializedFontMap();
- }
return mSerializedFontMap;
}
}
@@ -234,9 +259,10 @@ public final class FontManagerService extends IFontManager.Stub {
FontManager.RESULT_ERROR_VERSION_MISMATCH,
"The base config version is older than current.");
}
- mUpdatableFontDir.installFontFile(fd, pkcs7Signature);
- // Create updated font map in the next getSerializedSystemFontMap() call.
- mSerializedFontMap = null;
+ try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) {
+ mUpdatableFontDir.installFontFile(fd, pkcs7Signature);
+ mSerializedFontMap = buildNewSerializedFontMap();
+ }
}
}
@@ -246,7 +272,12 @@ public final class FontManagerService extends IFontManager.Stub {
FontManager.RESULT_ERROR_FONT_UPDATER_DISABLED,
"The font updater is disabled.");
}
- mUpdatableFontDir.clearUpdates();
+ synchronized (FontManagerService.this) {
+ try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) {
+ mUpdatableFontDir.clearUpdates();
+ mSerializedFontMap = buildNewSerializedFontMap();
+ }
+ }
}
/* package */ Map<String, File> getFontFileMap() {
diff --git a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
index b0bc65bc7787..0cb704507f7a 100644
--- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
+++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
@@ -142,11 +142,9 @@ final class UpdatableFontDir {
mFsverityUtil = fsverityUtil;
mConfigFile = configFile;
mTmpConfigFile = new File(configFile.getAbsoluteFile() + ".tmp");
- loadFontFileMap();
}
- private void loadFontFileMap() {
- // TODO: SIGBUS crash protection
+ /* package */ void loadFontFileMap() {
synchronized (UpdatableFontDir.this) {
boolean success = false;
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 23c70ee69514..2e4200c1f7d9 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -289,6 +289,8 @@ public class InputManagerService extends IInputManager.Stub
private static native void nativeCancelVibrate(long ptr, int deviceId, int token);
private static native boolean nativeIsVibrating(long ptr, int deviceId);
private static native int[] nativeGetVibratorIds(long ptr, int deviceId);
+ private static native int nativeGetBatteryCapacity(long ptr, int deviceId);
+ private static native int nativeGetBatteryStatus(long ptr, int deviceId);
private static native void nativeReloadKeyboardLayouts(long ptr);
private static native void nativeReloadDeviceAliases(long ptr);
private static native String nativeDump(long ptr);
@@ -1818,8 +1820,7 @@ public class InputManagerService extends IInputManager.Stub
}
private void updateMaximumObscuringOpacityForTouchFromSettings() {
- final float opacity = InputManager.getInstance().getMaximumObscuringOpacityForTouch(
- mContext);
+ final float opacity = InputManager.getInstance().getMaximumObscuringOpacityForTouch();
if (opacity < 0 || opacity > 1) {
Log.e(TAG, "Invalid maximum obscuring opacity " + opacity
+ ", it should be >= 0 and <= 1, rejecting update.");
@@ -2009,6 +2010,18 @@ public class InputManagerService extends IInputManager.Stub
// Binder call
@Override
+ public int getBatteryStatus(int deviceId) {
+ return nativeGetBatteryStatus(mPtr, deviceId);
+ }
+
+ // Binder call
+ @Override
+ public int getBatteryCapacity(int deviceId) {
+ return nativeGetBatteryCapacity(mPtr, deviceId);
+ }
+
+ // Binder call
+ @Override
public void setPointerIconType(int iconId) {
nativeSetPointerIconType(mPtr, iconId);
}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 6308ace26011..e5b53501d6e3 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -4131,48 +4131,52 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
@Override
@GuardedBy("mMethodMap")
- public void startProtoDump(byte[] protoDump, int source, String where) {
- if (protoDump == null && source != IME_TRACING_FROM_IMMS) {
- // Dump not triggered from IMMS, but no proto information provided.
- return;
- }
- ImeTracing tracingInstance = ImeTracing.getInstance();
- if (!tracingInstance.isAvailable() || !tracingInstance.isEnabled()) {
- return;
- }
-
- ProtoOutputStream proto = new ProtoOutputStream();
- switch (source) {
- case ImeTracing.IME_TRACING_FROM_CLIENT:
- final long client_token = proto.start(InputMethodClientsTraceFileProto.ENTRY);
- proto.write(InputMethodClientsTraceProto.ELAPSED_REALTIME_NANOS,
- SystemClock.elapsedRealtimeNanos());
- proto.write(InputMethodClientsTraceProto.WHERE, where);
- proto.write(InputMethodClientsTraceProto.CLIENT, protoDump);
- proto.end(client_token);
- break;
- case ImeTracing.IME_TRACING_FROM_IMS:
- final long service_token = proto.start(InputMethodServiceTraceFileProto.ENTRY);
- proto.write(InputMethodServiceTraceProto.ELAPSED_REALTIME_NANOS,
- SystemClock.elapsedRealtimeNanos());
- proto.write(InputMethodServiceTraceProto.WHERE, where);
- proto.write(InputMethodServiceTraceProto.INPUT_METHOD_SERVICE, protoDump);
- proto.end(service_token);
- break;
- case IME_TRACING_FROM_IMMS:
- final long managerservice_token =
- proto.start(InputMethodManagerServiceTraceFileProto.ENTRY);
- proto.write(InputMethodManagerServiceTraceProto.ELAPSED_REALTIME_NANOS,
- SystemClock.elapsedRealtimeNanos());
- proto.write(InputMethodManagerServiceTraceProto.WHERE, where);
- dumpDebug(proto, InputMethodManagerServiceTraceProto.INPUT_METHOD_MANAGER_SERVICE);
- proto.end(managerservice_token);
- break;
- default:
- // Dump triggered by a source not recognised.
+ public void startProtoDump(byte[] protoDump, int source, String where,
+ IVoidResultCallback resultCallback) {
+ CallbackUtils.onResult(resultCallback, () -> {
+ if (protoDump == null && source != IME_TRACING_FROM_IMMS) {
+ // Dump not triggered from IMMS, but no proto information provided.
return;
- }
- tracingInstance.addToBuffer(proto, source);
+ }
+ ImeTracing tracingInstance = ImeTracing.getInstance();
+ if (!tracingInstance.isAvailable() || !tracingInstance.isEnabled()) {
+ return;
+ }
+
+ ProtoOutputStream proto = new ProtoOutputStream();
+ switch (source) {
+ case ImeTracing.IME_TRACING_FROM_CLIENT:
+ final long client_token = proto.start(InputMethodClientsTraceFileProto.ENTRY);
+ proto.write(InputMethodClientsTraceProto.ELAPSED_REALTIME_NANOS,
+ SystemClock.elapsedRealtimeNanos());
+ proto.write(InputMethodClientsTraceProto.WHERE, where);
+ proto.write(InputMethodClientsTraceProto.CLIENT, protoDump);
+ proto.end(client_token);
+ break;
+ case ImeTracing.IME_TRACING_FROM_IMS:
+ final long service_token = proto.start(InputMethodServiceTraceFileProto.ENTRY);
+ proto.write(InputMethodServiceTraceProto.ELAPSED_REALTIME_NANOS,
+ SystemClock.elapsedRealtimeNanos());
+ proto.write(InputMethodServiceTraceProto.WHERE, where);
+ proto.write(InputMethodServiceTraceProto.INPUT_METHOD_SERVICE, protoDump);
+ proto.end(service_token);
+ break;
+ case IME_TRACING_FROM_IMMS:
+ final long managerservice_token =
+ proto.start(InputMethodManagerServiceTraceFileProto.ENTRY);
+ proto.write(InputMethodManagerServiceTraceProto.ELAPSED_REALTIME_NANOS,
+ SystemClock.elapsedRealtimeNanos());
+ proto.write(InputMethodManagerServiceTraceProto.WHERE, where);
+ dumpDebug(proto,
+ InputMethodManagerServiceTraceProto.INPUT_METHOD_MANAGER_SERVICE);
+ proto.end(managerservice_token);
+ break;
+ default:
+ // Dump triggered by a source not recognised.
+ return;
+ }
+ tracingInstance.addToBuffer(proto, source);
+ });
}
@BinderThread
@@ -4183,40 +4187,44 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
@Override
- public void startImeTrace() {
- ImeTracing.getInstance().startTrace(null /* printwriter */);
- ArrayMap<IBinder, ClientState> clients;
- synchronized (mMethodMap) {
- clients = new ArrayMap<>(mClients);
- }
- for (ClientState state : clients.values()) {
- if (state != null) {
- try {
- state.client.setImeTraceEnabled(true /* enabled */);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error while trying to enable ime trace on client window", e);
+ public void startImeTrace(IVoidResultCallback resultCallback) {
+ CallbackUtils.onResult(resultCallback, () -> {
+ ImeTracing.getInstance().startTrace(null /* printwriter */);
+ ArrayMap<IBinder, ClientState> clients;
+ synchronized (mMethodMap) {
+ clients = new ArrayMap<>(mClients);
+ }
+ for (ClientState state : clients.values()) {
+ if (state != null) {
+ try {
+ state.client.setImeTraceEnabled(true /* enabled */);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error while trying to enable ime trace on client window", e);
+ }
}
}
- }
+ });
}
@BinderThread
@Override
- public void stopImeTrace() {
- ImeTracing.getInstance().stopTrace(null /* printwriter */);
- ArrayMap<IBinder, ClientState> clients;
- synchronized (mMethodMap) {
- clients = new ArrayMap<>(mClients);
- }
- for (ClientState state : clients.values()) {
- if (state != null) {
- try {
- state.client.setImeTraceEnabled(false /* enabled */);
- } catch (RemoteException e) {
- Slog.e(TAG, "Error while trying to disable ime trace on client window", e);
+ public void stopImeTrace(IVoidResultCallback resultCallback) {
+ CallbackUtils.onResult(resultCallback, () -> {
+ ImeTracing.getInstance().stopTrace(null /* printwriter */);
+ ArrayMap<IBinder, ClientState> clients;
+ synchronized (mMethodMap) {
+ clients = new ArrayMap<>(mClients);
+ }
+ for (ClientState state : clients.values()) {
+ if (state != null) {
+ try {
+ state.client.setImeTraceEnabled(false /* enabled */);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error while trying to disable ime trace on client window", e);
+ }
}
}
- }
+ });
}
@GuardedBy("mMethodMap")
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 7f9c76634422..6fec9063ba94 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -1868,7 +1868,9 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
- public void startProtoDump(byte[] clientProtoDump, int source, String where) {
+ public void startProtoDump(byte[] clientProtoDump, int source, String where,
+ IVoidResultCallback resultCallback) {
+ CallbackUtils.onResult(resultCallback, () -> { });
}
@BinderThread
@@ -1879,12 +1881,14 @@ public final class MultiClientInputMethodManagerService {
@BinderThread
@Override
- public void startImeTrace() {
+ public void startImeTrace(IVoidResultCallback resultCallback) {
+ CallbackUtils.onResult(resultCallback, () -> { });
}
@BinderThread
@Override
- public void stopImeTrace() {
+ public void stopImeTrace(IVoidResultCallback resultCallback) {
+ CallbackUtils.onResult(resultCallback, () -> { });
}
}
}
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 dc1a26ae6fea..785e6745087f 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -16,6 +16,7 @@
package com.android.server.location.contexthub;
+import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -320,6 +321,10 @@ public class ContextHubService extends IContextHubService.Stub {
@Override
public void onNanoAppDisabled(long nanoAppId) {
}
+
+ @Override
+ public void onClientAuthorizationChanged(long nanoAppId, int authorization) {
+ }
};
}
@@ -697,6 +702,7 @@ public class ContextHubService extends IContextHubService.Stub {
*
* @param contextHubId the ID of the hub this client is attached to
* @param clientCallback the client interface to register with the service
+ * @param attributionTag an optional attribution tag within the given package
* @return the generated client interface, null if registration was unsuccessful
* @throws IllegalArgumentException if contextHubId is not a valid ID
* @throws IllegalStateException if max number of clients have already registered
@@ -704,7 +710,8 @@ public class ContextHubService extends IContextHubService.Stub {
*/
@Override
public IContextHubClient createClient(
- int contextHubId, IContextHubClientCallback clientCallback) throws RemoteException {
+ int contextHubId, IContextHubClientCallback clientCallback,
+ @Nullable String attributionTag) throws RemoteException {
checkPermissions();
if (!isValidContextHubId(contextHubId)) {
throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
@@ -723,13 +730,15 @@ public class ContextHubService extends IContextHubService.Stub {
* @param contextHubId the ID of the hub this client is attached to
* @param pendingIntent the PendingIntent associated with this client
* @param nanoAppId the ID of the nanoapp PendingIntent events will be sent for
+ * @param attributionTag an optional attribution tag within the given package
* @return the generated client interface
* @throws IllegalArgumentException if hubInfo does not represent a valid hub
* @throws IllegalStateException if there were too many registered clients at the service
*/
@Override
public IContextHubClient createPendingIntentClient(
- int contextHubId, PendingIntent pendingIntent, long nanoAppId) throws RemoteException {
+ int contextHubId, PendingIntent pendingIntent, long nanoAppId,
+ @Nullable String attributionTag) throws RemoteException {
checkPermissions();
if (!isValidContextHubId(contextHubId)) {
throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e32c00fe9a39..6843733eea9f 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -377,7 +377,8 @@ public class NotificationManagerService extends SystemService {
static final String[] DEFAULT_ALLOWED_ADJUSTMENTS = new String[] {
Adjustment.KEY_CONTEXTUAL_ACTIONS,
- Adjustment.KEY_TEXT_REPLIES};
+ Adjustment.KEY_TEXT_REPLIES,
+ Adjustment.KEY_NOT_CONVERSATION};
static final String[] NON_BLOCKABLE_DEFAULT_ROLES = new String[] {
RoleManager.ROLE_DIALER,
@@ -2313,6 +2314,13 @@ public class NotificationManagerService extends SystemService {
} else if ("false".equals(value)) {
mAssistants.disallowAdjustmentType(Adjustment.KEY_RANKING_SCORE);
}
+ } else if (SystemUiDeviceConfigFlags.ENABLE_NAS_NOT_CONVERSATION.equals(name)) {
+ String value = properties.getString(name, null);
+ if ("true".equals(value)) {
+ mAssistants.allowAdjustmentType(Adjustment.KEY_NOT_CONVERSATION);
+ } else if ("false".equals(value)) {
+ mAssistants.disallowAdjustmentType(Adjustment.KEY_NOT_CONVERSATION);
+ }
}
}
};
@@ -9302,21 +9310,30 @@ public class NotificationManagerService extends SystemService {
Slog.v(TAG, "onNotificationEnqueuedLocked() called with: r = [" + r + "]");
}
final StatusBarNotification sbn = r.getSbn();
- notifyAssistantLocked(
- sbn,
- r.getNotificationType(),
- true /* sameUserOnly */,
- (assistant, sbnHolder) -> {
- try {
- if (debug) {
- Slog.v(TAG,
- "calling onNotificationEnqueuedWithChannel " + sbnHolder);
- }
- assistant.onNotificationEnqueuedWithChannel(sbnHolder, r.getChannel());
- } catch (RemoteException ex) {
- Slog.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
+
+ for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
+ boolean sbnVisible = isVisibleToListener(
+ sbn, r.getNotificationType(), info)
+ && info.isSameUser(r.getUserId());
+ if (sbnVisible) {
+ TrimCache trimCache = new TrimCache(sbn);
+ final INotificationListener assistant = (INotificationListener) info.service;
+ final StatusBarNotification sbnToPost = trimCache.ForListener(info);
+ final StatusBarNotificationHolder sbnHolder =
+ new StatusBarNotificationHolder(sbnToPost);
+ try {
+ if (debug) {
+ Slog.v(TAG,
+ "calling onNotificationEnqueuedWithChannel " + sbnHolder);
}
- });
+ final NotificationRankingUpdate update = makeRankingUpdateLocked(info);
+ assistant.onNotificationEnqueuedWithChannel(sbnHolder, r.getChannel(),
+ update);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
+ }
+ }
+ }
}
@GuardedBy("mNotificationLock")
diff --git a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
index f59934fd6810..d7bc3bb8af28 100644
--- a/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
+++ b/services/core/java/com/android/server/notification/ValidateNotificationPeople.java
@@ -523,27 +523,39 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
if (VERBOSE) Slog.i(TAG, "Executing: validation for: " + mKey);
long timeStartMs = System.currentTimeMillis();
for (final String handle: mPendingLookups) {
+ final String cacheKey = getCacheKey(mContext.getUserId(), handle);
LookupResult lookupResult = null;
- final Uri uri = Uri.parse(handle);
- if ("tel".equals(uri.getScheme())) {
- if (DEBUG) Slog.d(TAG, "checking telephone URI: " + handle);
- lookupResult = resolvePhoneContact(mContext, uri.getSchemeSpecificPart());
- } else if ("mailto".equals(uri.getScheme())) {
- if (DEBUG) Slog.d(TAG, "checking mailto URI: " + handle);
- lookupResult = resolveEmailContact(mContext, uri.getSchemeSpecificPart());
- } else if (handle.startsWith(Contacts.CONTENT_LOOKUP_URI.toString())) {
- if (DEBUG) Slog.d(TAG, "checking lookup URI: " + handle);
- lookupResult = searchContacts(mContext, uri);
- } else {
- lookupResult = new LookupResult(); // invalid person for the cache
- if (!"name".equals(uri.getScheme())) {
- Slog.w(TAG, "unsupported URI " + handle);
+ boolean cacheHit = false;
+ synchronized (mPeopleCache) {
+ lookupResult = mPeopleCache.get(cacheKey);
+ if (lookupResult != null && !lookupResult.isExpired()) {
+ // The name wasn't already added to the cache, no need to retry
+ cacheHit = true;
+ }
+ }
+ if (!cacheHit) {
+ final Uri uri = Uri.parse(handle);
+ if ("tel".equals(uri.getScheme())) {
+ if (DEBUG) Slog.d(TAG, "checking telephone URI: " + handle);
+ lookupResult = resolvePhoneContact(mContext, uri.getSchemeSpecificPart());
+ } else if ("mailto".equals(uri.getScheme())) {
+ if (DEBUG) Slog.d(TAG, "checking mailto URI: " + handle);
+ lookupResult = resolveEmailContact(mContext, uri.getSchemeSpecificPart());
+ } else if (handle.startsWith(Contacts.CONTENT_LOOKUP_URI.toString())) {
+ if (DEBUG) Slog.d(TAG, "checking lookup URI: " + handle);
+ lookupResult = searchContacts(mContext, uri);
+ } else {
+ lookupResult = new LookupResult(); // invalid person for the cache
+ if (!"name".equals(uri.getScheme())) {
+ Slog.w(TAG, "unsupported URI " + handle);
+ }
}
}
if (lookupResult != null) {
- synchronized (mPeopleCache) {
- final String cacheKey = getCacheKey(mContext.getUserId(), handle);
- mPeopleCache.put(cacheKey, lookupResult);
+ if (!cacheHit) {
+ synchronized (mPeopleCache) {
+ mPeopleCache.put(cacheKey, lookupResult);
+ }
}
if (DEBUG) {
Slog.d(TAG, "lookup contactAffinity is " + lookupResult.getAffinity());
@@ -580,4 +592,3 @@ public class ValidateNotificationPeople implements NotificationSignalExtractor {
}
}
}
-
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index e0b57e4ce42f..402f6467e82d 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -118,8 +118,8 @@ public class BackgroundDexOptService extends JobService {
// Schedule a one-off job which scans installed packages and updates
// out-of-date oat files.
js.schedule(new JobInfo.Builder(JOB_POST_BOOT_UPDATE, sDexoptServiceName)
- .setMinimumLatency(TimeUnit.MINUTES.toMillis(1))
- .setOverrideDeadline(TimeUnit.MINUTES.toMillis(1))
+ .setMinimumLatency(TimeUnit.MINUTES.toMillis(10))
+ .setOverrideDeadline(TimeUnit.MINUTES.toMillis(60))
.build());
// Schedule a daily job which scans installed packages and compiles
diff --git a/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java b/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
index da65fe2bc0ab..c65c2b112706 100644
--- a/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
+++ b/services/core/java/com/android/server/pm/DynamicCodeLoggingService.java
@@ -234,7 +234,7 @@ public class DynamicCodeLoggingService extends JobService {
List<EventLog.Event> events = new ArrayList<>();
EventLog.readEvents(tags, events);
-
+ Matcher matcher = EXECUTE_NATIVE_AUDIT_PATTERN.matcher("");
for (int i = 0; i < events.size(); ++i) {
if (mAuditWatchingStopRequested) {
Log.w(TAG, "Stopping AuditWatchingJob run at scheduler request");
@@ -259,7 +259,9 @@ public class DynamicCodeLoggingService extends JobService {
// And then use a regular expression to verify it's one of the messages we're
// interested in and to extract the path of the file being loaded.
- Matcher matcher = EXECUTE_NATIVE_AUDIT_PATTERN.matcher(message);
+ // Reuse the Matcher to avoid unnecessary string garbage caused by libcore's
+ // regex matching.
+ matcher.reset(message);
if (!matcher.matches()) {
continue;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f772f63a08ac..f68113d5520a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -347,6 +347,7 @@ import com.android.internal.content.PackageHelper;
import com.android.internal.content.om.OverlayConfig;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.SomeArgs;
+import com.android.internal.policy.AttributeCache;
import com.android.internal.telephony.CarrierAppUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ConcurrentUtils;
@@ -355,7 +356,6 @@ import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.permission.persistence.RuntimePermissionsPersistence;
-import com.android.server.AttributeCache;
import com.android.server.DeviceIdleInternal;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
@@ -18819,9 +18819,11 @@ public class PackageManagerService extends IPackageManager.Stub
final VersionInfo versionInfo = request.versionInfos.get(installPackageName);
final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
+ final boolean isRollback = installArgs != null
+ && installArgs.installReason == PackageManager.INSTALL_REASON_ROLLBACK;
final boolean compatMatch = verifySignatures(signatureCheckPs,
disabledPkgSetting, parsedPackage.getSigningDetails(), compareCompat,
- compareRecover);
+ compareRecover, isRollback);
// The new KeySets will be re-added later in the scanning process.
if (compatMatch) {
removeAppKeySetData = true;
@@ -19791,6 +19793,7 @@ public class PackageManagerService extends IPackageManager.Stub
final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
final boolean virtualPreload =
((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
+ final boolean isRollback = args.installReason == PackageManager.INSTALL_REASON_ROLLBACK;
@ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
if (args.move != null) {
// moving a complete application; perform an initial scan on the new install location
@@ -19971,7 +19974,8 @@ public class PackageManagerService extends IPackageManager.Stub
parsedPackage);
// We don't care about disabledPkgSetting on install for now.
final boolean compatMatch = verifySignatures(signatureCheckPs, null,
- parsedPackage.getSigningDetails(), compareCompat, compareRecover);
+ parsedPackage.getSigningDetails(), compareCompat, compareRecover,
+ isRollback);
// The new KeySets will be re-added later in the scanning process.
if (compatMatch) {
synchronized (mLock) {
@@ -20248,15 +20252,23 @@ public class PackageManagerService extends IPackageManager.Stub
+ pkgName11);
}
} else {
+ SigningDetails parsedPkgSigningDetails = parsedPackage.getSigningDetails();
+ SigningDetails oldPkgSigningDetails = oldPackage.getSigningDetails();
// default to original signature matching
- if (!parsedPackage.getSigningDetails().checkCapability(
- oldPackage.getSigningDetails(),
+ if (!parsedPkgSigningDetails.checkCapability(oldPkgSigningDetails,
SigningDetails.CertCapabilities.INSTALLED_DATA)
- && !oldPackage.getSigningDetails().checkCapability(
- parsedPackage.getSigningDetails(),
+ && !oldPkgSigningDetails.checkCapability(parsedPkgSigningDetails,
SigningDetails.CertCapabilities.ROLLBACK)) {
- throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
- "New package has a different signature: " + pkgName11);
+ // Allow the update to proceed if this is a rollback and the parsed
+ // package's current signing key is the current signer or in the lineage
+ // of the old package; this allows a rollback to a previously installed
+ // version after an app's signing key has been rotated without requiring
+ // the rollback capability on the previous signing key.
+ if (!isRollback || !oldPkgSigningDetails.hasAncestorOrSelf(
+ parsedPkgSigningDetails)) {
+ throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
+ "New package has a different signature: " + pkgName11);
+ }
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index ee94b8599625..8015063812e6 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -624,7 +624,7 @@ public class PackageManagerServiceUtils {
*/
public static boolean verifySignatures(PackageSetting pkgSetting,
PackageSetting disabledPkgSetting, PackageParser.SigningDetails parsedSignatures,
- boolean compareCompat, boolean compareRecover)
+ boolean compareCompat, boolean compareRecover, boolean isRollback)
throws PackageManagerException {
final String packageName = pkgSetting.name;
boolean compatMatch = false;
@@ -658,6 +658,13 @@ public class PackageManagerServiceUtils {
match = matchSignatureInSystem(pkgSetting, disabledPkgSetting);
}
+ if (!match && isRollback) {
+ // Since a rollback can only be initiated for an APK previously installed on the
+ // device allow rolling back to a previous signing key even if the rollback
+ // capability has not been granted.
+ match = pkgSetting.signatures.mSigningDetails.hasAncestorOrSelf(parsedSignatures);
+ }
+
if (!match) {
throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"Package " + packageName +
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 89e7986fc4bc..a407e8e1b7df 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -188,7 +188,6 @@ import android.view.WindowManagerPolicyConstants;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.autofill.AutofillManagerInternal;
@@ -201,7 +200,9 @@ import com.android.internal.os.RoSystemProperties;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
import com.android.internal.policy.KeyInterceptionInfo;
+import com.android.internal.policy.LogDecelerateInterpolator;
import com.android.internal.policy.PhoneWindow;
+import com.android.internal.policy.TransitionAnimation;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ArrayUtils;
import com.android.server.ExtconStateObserver;
@@ -228,7 +229,6 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
-import java.util.List;
/**
* WindowManagerPolicy implementation for the Android phone UI. This
@@ -582,7 +582,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private final SparseArray<KeyCharacterMap.FallbackAction> mFallbackActions =
new SparseArray<KeyCharacterMap.FallbackAction>();
- private final LogDecelerateInterpolator mLogDecelerateInterpolator
+ private final com.android.internal.policy.LogDecelerateInterpolator mLogDecelerateInterpolator
= new LogDecelerateInterpolator(100, 0);
private final MutableBoolean mTmpBoolean = new MutableBoolean(false);
@@ -2484,28 +2484,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public Animation createHiddenByKeyguardExit(boolean onWallpaper,
boolean goingToNotificationShade, boolean subtleAnimation) {
- if (goingToNotificationShade) {
- return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in);
- }
-
- final int resource;
- if (subtleAnimation) {
- resource = R.anim.lock_screen_behind_enter_subtle;
- } else if (onWallpaper) {
- resource = R.anim.lock_screen_behind_enter_wallpaper;
- } else {
- resource = R.anim.lock_screen_behind_enter;
- }
-
- AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, resource);
-
- // TODO: Use XML interpolators when we have log interpolators available in XML.
- final List<Animation> animations = set.getAnimations();
- for (int i = animations.size() - 1; i >= 0; --i) {
- animations.get(i).setInterpolator(mLogDecelerateInterpolator);
- }
-
- return set;
+ return TransitionAnimation.createHiddenByKeyguardExit(mContext,
+ mLogDecelerateInterpolator, onWallpaper, goingToNotificationShade, subtleAnimation);
}
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index e12991a220c9..9560f59924de 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -563,6 +563,7 @@ class Rollback {
params.setRequestDowngrade(true);
params.setRequiredInstalledVersionCode(
pkgRollbackInfo.getVersionRolledBackFrom().getLongVersionCode());
+ params.setInstallReason(PackageManager.INSTALL_REASON_ROLLBACK);
if (isStaged()) {
params.setStaged();
}
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java
index 9d21b9241c0d..132883e4a041 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/services/core/java/com/android/server/vcn/Vcn.java
@@ -168,8 +168,8 @@ public class Vcn extends Handler {
@NonNull NetworkRequest request, int score, int providerId) {
if (score > getNetworkScore()) {
Slog.v(getLogTag(),
- "Request " + request.requestId + " already satisfied by higher-scoring ("
- + score + ") network from provider " + providerId);
+ "Request already satisfied by higher-scoring (" + score + ") network from "
+ + "provider " + providerId + ": " + request);
return;
}
@@ -177,8 +177,7 @@ public class Vcn extends Handler {
for (VcnGatewayConnectionConfig gatewayConnectionConfig : mVcnGatewayConnections.keySet()) {
if (requestSatisfiedByGatewayConnectionConfig(request, gatewayConnectionConfig)) {
Slog.v(getLogTag(),
- "Request " + request.requestId
- + " satisfied by existing VcnGatewayConnection");
+ "Request already satisfied by existing VcnGatewayConnection: " + request);
return;
}
}
@@ -202,12 +201,12 @@ public class Vcn extends Handler {
private boolean requestSatisfiedByGatewayConnectionConfig(
@NonNull NetworkRequest request, @NonNull VcnGatewayConnectionConfig config) {
- final NetworkCapabilities configCaps = new NetworkCapabilities();
+ final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
for (int cap : config.getAllExposedCapabilities()) {
- configCaps.addCapability(cap);
+ builder.addCapability(cap);
}
- return request.networkCapabilities.satisfiedByNetworkCapabilities(configCaps);
+ return request.canBeSatisfiedBy(builder.build());
}
private String getLogTag() {
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 703bfab6d868..3cfa00eb6079 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -963,18 +963,18 @@ public class VcnGatewayConnection extends StateMachine {
@VisibleForTesting(visibility = Visibility.PRIVATE)
static NetworkCapabilities buildNetworkCapabilities(
@NonNull VcnGatewayConnectionConfig gatewayConnectionConfig) {
- final NetworkCapabilities caps = new NetworkCapabilities();
+ final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
- caps.addTransportType(TRANSPORT_CELLULAR);
- caps.addCapability(NET_CAPABILITY_NOT_CONGESTED);
- caps.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ builder.addTransportType(TRANSPORT_CELLULAR);
+ builder.addCapability(NET_CAPABILITY_NOT_CONGESTED);
+ builder.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
// Add exposed capabilities
for (int cap : gatewayConnectionConfig.getAllExposedCapabilities()) {
- caps.addCapability(cap);
+ builder.addCapability(cap);
}
- return caps;
+ return builder.build();
}
private static LinkProperties buildConnectedLinkProperties(
diff --git a/services/core/java/com/android/server/vcn/VcnNetworkProvider.java b/services/core/java/com/android/server/vcn/VcnNetworkProvider.java
index 7f5b23c9db6f..b9babae4c6b7 100644
--- a/services/core/java/com/android/server/vcn/VcnNetworkProvider.java
+++ b/services/core/java/com/android/server/vcn/VcnNetworkProvider.java
@@ -21,9 +21,9 @@ import android.content.Context;
import android.net.NetworkProvider;
import android.net.NetworkRequest;
import android.os.Looper;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
-import android.util.SparseArray;
import java.util.Objects;
import java.util.Set;
@@ -40,7 +40,13 @@ public class VcnNetworkProvider extends NetworkProvider {
private static final String TAG = VcnNetworkProvider.class.getSimpleName();
private final Set<NetworkRequestListener> mListeners = new ArraySet<>();
- private final SparseArray<NetworkRequestEntry> mRequests = new SparseArray<>();
+
+ /**
+ * Cache of NetworkRequest(s), scores and network providers, keyed by NetworkRequest
+ *
+ * <p>NetworkRequests are immutable once created, and therefore can be used as stable keys.
+ */
+ private final ArrayMap<NetworkRequest, NetworkRequestEntry> mRequests = new ArrayMap<>();
public VcnNetworkProvider(Context context, Looper looper) {
super(context, looper, VcnNetworkProvider.class.getSimpleName());
@@ -51,8 +57,8 @@ public class VcnNetworkProvider extends NetworkProvider {
mListeners.add(listener);
// Send listener all cached requests
- for (int i = 0; i < mRequests.size(); i++) {
- notifyListenerForEvent(listener, mRequests.valueAt(i));
+ for (NetworkRequestEntry entry : mRequests.values()) {
+ notifyListenerForEvent(listener, entry);
}
}
@@ -75,7 +81,9 @@ public class VcnNetworkProvider extends NetworkProvider {
request, score, providerId));
final NetworkRequestEntry entry = new NetworkRequestEntry(request, score, providerId);
- mRequests.put(request.requestId, entry);
+
+ // NetworkRequests are immutable once created, and therefore can be used as stable keys.
+ mRequests.put(request, entry);
// TODO(b/176939047): Intelligently route requests to prioritized VcnInstances (based on
// Default Data Sub, or similar)
@@ -86,7 +94,7 @@ public class VcnNetworkProvider extends NetworkProvider {
@Override
public void onNetworkRequestWithdrawn(@NonNull NetworkRequest request) {
- mRequests.remove(request.requestId);
+ mRequests.remove(request);
}
private static class NetworkRequestEntry {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 3bb4c74b7dc0..4e359f2577c2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -303,13 +303,13 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.ReferrerIntent;
+import com.android.internal.policy.AttributeCache;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
-import com.android.server.AttributeCache;
import com.android.server.LocalServices;
import com.android.server.am.AppTimeTracker;
import com.android.server.am.PendingIntentRecord;
@@ -1431,14 +1431,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
/**
- * @return {@code true} if bar shown within a given rectangle is allowed to be transparent
+ * @return {@code true} if bar shown within a given rectangle is allowed to be fully transparent
* when the current activity is displayed.
*/
- boolean isTransparentBarAllowed(Rect rect) {
- // TODO(b/175482966): Allow status and navigation bars to be semi-transparent black
- // in letterbox mode.
- return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect)
- || mWmService.isLetterboxActivityCornersRounded();
+ boolean isFullyTransparentBarAllowed(Rect rect) {
+ return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
}
/**
@@ -2183,6 +2180,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
/** @return Root task of this activity, null if there is no task. */
+ @Nullable
Task getRootTask() {
return task != null ? task.getRootTask() : null;
}
@@ -2191,6 +2189,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return task != null ? task.getRootTaskId() : INVALID_TASK_ID;
}
+ /** @return the first organized parent task. */
+ @Nullable
+ Task getOrganizedTask() {
+ return task != null ? task.getOrganizedTask() : null;
+ }
+
@Override
@Nullable
TaskDisplayArea getDisplayArea() {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 9e2e58fddd18..64b1e042a58c 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -232,13 +232,13 @@ import com.android.internal.app.ProcessMap;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.TransferPipe;
+import com.android.internal.policy.AttributeCache;
import com.android.internal.policy.KeyguardDismissCallback;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.function.pooled.PooledLambda;
-import com.android.server.AttributeCache;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
@@ -486,13 +486,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
* Whether normal application switches are allowed; a call to {@link #stopAppSwitches()
* disables this.
*/
- private boolean mAppSwitchesAllowed = true;
+ private volatile boolean mAppSwitchesAllowed = true;
/**
* Last stop app switches time, apps finished before this time cannot start background activity
* even if they are in grace period.
*/
- private long mLastStopAppSwitchesTime;
+ private volatile long mLastStopAppSwitchesTime;
IActivityController mController = null;
boolean mControllerIsAMonkey = false;
@@ -698,6 +698,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
int OOM_ADJUSTMENT = 1;
int LRU_UPDATE = 2;
int PROCESS_CHANGE = 3;
+ int START_SERVICE = 4;
int caller() default NONE;
}
@@ -4744,6 +4745,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
/** A uid is considered to be foreground if it has a visible non-toast window. */
+ @HotPath(caller = HotPath.START_SERVICE)
boolean hasActiveVisibleWindow(int uid) {
if (mVisibleActivityProcessTracker.hasVisibleActivity(uid)) {
return true;
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index f8b498797ff3..90070c8f5068 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -78,6 +78,10 @@ import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpe
import static com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation;
import static com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
+import static com.android.internal.policy.TransitionAnimation.THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN;
+import static com.android.internal.policy.TransitionAnimation.THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
+import static com.android.internal.policy.TransitionAnimation.THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN;
+import static com.android.internal.policy.TransitionAnimation.THUMBNAIL_TRANSITION_EXIT_SCALE_UP;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM;
import static com.android.server.wm.AppTransitionProto.APP_TRANSITION_STATE;
@@ -96,9 +100,6 @@ import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
-import android.content.res.ResourceId;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -136,15 +137,12 @@ import android.view.animation.PathInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
-import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.policy.TransitionAnimation;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.DumpUtils.Dump;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
-import com.android.server.AttributeCache;
-import com.android.server.wm.animation.ClipRectLRAnimation;
-import com.android.server.wm.animation.ClipRectTBAnimation;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -184,6 +182,8 @@ public class AppTransition implements Dump {
private final WindowManagerService mService;
private final DisplayContent mDisplayContent;
+ private final TransitionAnimation mTransitionAnimation;
+
private @TransitionFlags int mNextAppTransitionFlags = 0;
private final ArrayList<Integer> mNextAppTransitionRequests = new ArrayList<>();
private @TransitionOldType int mLastUsedAppTransition = TRANSIT_OLD_UNSET;
@@ -212,12 +212,6 @@ public class AppTransition implements Dump {
private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
private boolean mNextAppTransitionOverrideRequested;
- // These are the possible states for the enter/exit activities during a thumbnail transition
- private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
- private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_UP = 1;
- private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN = 2;
- private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;
-
private String mNextAppTransitionPackage;
// Used for thumbnail transitions. True if we're scaling up, false if scaling down
private boolean mNextAppTransitionScaleUp;
@@ -283,6 +277,7 @@ public class AppTransition implements Dump {
mService = service;
mHandler = new Handler(service.mH.getLooper());
mDisplayContent = displayContent;
+ mTransitionAnimation = new TransitionAnimation(context, DEBUG_ANIM, TAG);
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.linear_out_slow_in);
mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -555,242 +550,18 @@ public class AppTransition implements Dump {
/** Returns window animation style ID from {@link LayoutParams} or from system in some cases */
@VisibleForTesting
int getAnimationStyleResId(@NonNull LayoutParams lp) {
- int resId = lp.windowAnimations;
- if (lp.type == LayoutParams.TYPE_APPLICATION_STARTING) {
- // Note that we don't want application to customize starting window animation.
- // Since this window is specific for displaying while app starting,
- // application should not change its animation directly.
- // In this case, it will use system resource to get default animation.
- resId = mDefaultWindowAnimationStyleResId;
- }
- return resId;
- }
-
- private AttributeCache.Entry getCachedAnimations(LayoutParams lp) {
- if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: layout params pkg="
- + (lp != null ? lp.packageName : null)
- + " resId=0x" + (lp != null ? Integer.toHexString(lp.windowAnimations) : null));
- if (lp != null && lp.windowAnimations != 0) {
- // If this is a system resource, don't try to load it from the
- // application resources. It is nice to avoid loading application
- // resources if we can.
- String packageName = lp.packageName != null ? lp.packageName : "android";
- int resId = getAnimationStyleResId(lp);
- if ((resId&0xFF000000) == 0x01000000) {
- packageName = "android";
- }
- if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
- + packageName);
- return AttributeCache.instance().get(packageName, resId,
- com.android.internal.R.styleable.WindowAnimation, mCurrentUserId);
- }
- return null;
- }
-
- private AttributeCache.Entry getCachedAnimations(String packageName, int resId) {
- if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: package="
- + packageName + " resId=0x" + Integer.toHexString(resId));
- if (packageName != null) {
- if ((resId&0xFF000000) == 0x01000000) {
- packageName = "android";
- }
- if (DEBUG_ANIM) Slog.v(TAG, "Loading animations: picked package="
- + packageName);
- return AttributeCache.instance().get(packageName, resId,
- com.android.internal.R.styleable.WindowAnimation, mCurrentUserId);
- }
- return null;
- }
-
- Animation loadAnimationAttr(LayoutParams lp, int animAttr, int transit) {
- int resId = Resources.ID_NULL;
- Context context = mContext;
- if (animAttr >= 0) {
- AttributeCache.Entry ent = getCachedAnimations(lp);
- if (ent != null) {
- context = ent.context;
- resId = ent.array.getResourceId(animAttr, 0);
- }
- }
- resId = updateToTranslucentAnimIfNeeded(resId, transit);
- if (ResourceId.isValid(resId)) {
- return loadAnimationSafely(context, resId);
- }
- return null;
- }
-
- private Animation loadAnimationRes(LayoutParams lp, int resId) {
- Context context = mContext;
- if (ResourceId.isValid(resId)) {
- AttributeCache.Entry ent = getCachedAnimations(lp);
- if (ent != null) {
- context = ent.context;
- }
- return loadAnimationSafely(context, resId);
- }
- return null;
- }
-
- private Animation loadAnimationRes(String packageName, int resId) {
- if (ResourceId.isValid(resId)) {
- AttributeCache.Entry ent = getCachedAnimations(packageName, resId);
- if (ent != null) {
- return loadAnimationSafely(ent.context, resId);
- }
- }
- return null;
+ return mTransitionAnimation.getAnimationStyleResId(lp);
}
@VisibleForTesting
+ @Nullable
Animation loadAnimationSafely(Context context, int resId) {
- try {
- return AnimationUtils.loadAnimation(context, resId);
- } catch (NotFoundException e) {
- Slog.w(TAG, "Unable to load animation resource", e);
- return null;
- }
- }
-
- private int updateToTranslucentAnimIfNeeded(int anim, @TransitionOldType int transit) {
- if (transit == TRANSIT_OLD_TRANSLUCENT_ACTIVITY_OPEN
- && anim == R.anim.activity_open_enter) {
- return R.anim.activity_translucent_open_enter;
- }
- if (transit == TRANSIT_OLD_TRANSLUCENT_ACTIVITY_CLOSE
- && anim == R.anim.activity_close_exit) {
- return R.anim.activity_translucent_close_exit;
- }
- return anim;
- }
-
- /**
- * Compute the pivot point for an animation that is scaling from a small
- * rect on screen to a larger rect. The pivot point varies depending on
- * the distance between the inner and outer edges on both sides. This
- * function computes the pivot point for one dimension.
- * @param startPos Offset from left/top edge of outer rectangle to
- * left/top edge of inner rectangle.
- * @param finalScale The scaling factor between the size of the outer
- * and inner rectangles.
- */
- private static float computePivot(int startPos, float finalScale) {
-
- /*
- Theorem of intercepting lines:
-
- + + +-----------------------------------------------+
- | | | |
- | | | |
- | | | |
- | | | |
- x | y | | |
- | | | |
- | | | |
- | | | |
- | | | |
- | + | +--------------------+ |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | | | |
- | | +--------------------+ |
- | | |
- | | |
- | | |
- | | |
- | | |
- | | |
- | | |
- | +-----------------------------------------------+
- |
- |
- |
- |
- |
- |
- |
- |
- |
- + ++
- p ++
-
- scale = (x - y) / x
- <=> x = -y / (scale - 1)
- */
- final float denom = finalScale-1;
- if (Math.abs(denom) < .0001f) {
- return startPos;
- }
- return -startPos / denom;
+ return TransitionAnimation.loadAnimationSafely(context, resId, TAG);
}
- private Animation createScaleUpAnimationLocked(int transit, boolean enter,
- Rect containingFrame) {
- Animation a;
- getDefaultNextAppTransitionStartRect(mTmpRect);
- final int appWidth = containingFrame.width();
- final int appHeight = containingFrame.height();
- if (enter) {
- // Entering app zooms out from the center of the initial rect.
- float scaleW = mTmpRect.width() / (float) appWidth;
- float scaleH = mTmpRect.height() / (float) appHeight;
- Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
- computePivot(mTmpRect.left, scaleW),
- computePivot(mTmpRect.top, scaleH));
- scale.setInterpolator(mDecelerateInterpolator);
-
- Animation alpha = new AlphaAnimation(0, 1);
- alpha.setInterpolator(mThumbnailFadeOutInterpolator);
-
- AnimationSet set = new AnimationSet(false);
- set.addAnimation(scale);
- set.addAnimation(alpha);
- set.setDetachWallpaper(true);
- a = set;
- } else if (transit == TRANSIT_OLD_WALLPAPER_INTRA_OPEN
- || transit == TRANSIT_OLD_WALLPAPER_INTRA_CLOSE) {
- // If we are on top of the wallpaper, we need an animation that
- // correctly handles the wallpaper staying static behind all of
- // the animated elements. To do this, will just have the existing
- // element fade out.
- a = new AlphaAnimation(1, 0);
- a.setDetachWallpaper(true);
- } else {
- // For normal animations, the exiting element just holds in place.
- a = new AlphaAnimation(1, 1);
- }
-
- // Pick the desired duration. If this is an inter-activity transition,
- // it is the standard duration for that. Otherwise we use the longer
- // task transition duration.
- final long duration;
- switch (transit) {
- case TRANSIT_OLD_ACTIVITY_OPEN:
- case TRANSIT_OLD_ACTIVITY_CLOSE:
- duration = mConfigShortAnimTime;
- break;
- default:
- duration = DEFAULT_APP_TRANSITION_DURATION;
- break;
- }
- a.setDuration(duration);
- a.setFillAfter(true);
- a.setInterpolator(mDecelerateInterpolator);
- a.initialize(appWidth, appHeight, appWidth, appHeight);
- return a;
+ @Nullable
+ Animation loadAnimationAttr(LayoutParams lp, int animAttr, int transit) {
+ return mTransitionAnimation.loadAnimationAttr(lp, animAttr, transit);
}
private void getDefaultNextAppTransitionStartRect(Rect rect) {
@@ -825,27 +596,6 @@ public class AppTransition implements Dump {
}
/**
- * @return the duration of the last clip reveal animation
- */
- long getLastClipRevealTransitionDuration() {
- return mLastClipRevealTransitionDuration;
- }
-
- /**
- * @return the maximum distance the app surface is traveling of the last clip reveal animation
- */
- int getLastClipRevealMaxTranslation() {
- return mLastClipRevealMaxTranslation;
- }
-
- /**
- * @return true if in the last app transition had a clip reveal animation, false otherwise
- */
- boolean hadClipRevealAnimation() {
- return mLastHadClipReveal;
- }
-
- /**
* Calculates the duration for the clip reveal animation. If the clip is "cut off", meaning that
* the start rect is outside of the target rect, and there is a lot of movement going on.
*
@@ -867,137 +617,21 @@ public class AppTransition implements Dump {
(MAX_CLIP_REVEAL_TRANSITION_DURATION - DEFAULT_APP_TRANSITION_DURATION));
}
- private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame,
- Rect displayFrame) {
- final Animation anim;
- if (enter) {
- final int appWidth = appFrame.width();
- final int appHeight = appFrame.height();
-
- // mTmpRect will contain an area around the launcher icon that was pressed. We will
- // clip reveal from that area in the final area of the app.
- getDefaultNextAppTransitionStartRect(mTmpRect);
-
- float t = 0f;
- if (appHeight > 0) {
- t = (float) mTmpRect.top / displayFrame.height();
- }
- int translationY = mClipRevealTranslationY + (int)(displayFrame.height() / 7f * t);
- int translationX = 0;
- int translationYCorrection = translationY;
- int centerX = mTmpRect.centerX();
- int centerY = mTmpRect.centerY();
- int halfWidth = mTmpRect.width() / 2;
- int halfHeight = mTmpRect.height() / 2;
- int clipStartX = centerX - halfWidth - appFrame.left;
- int clipStartY = centerY - halfHeight - appFrame.top;
- boolean cutOff = false;
-
- // If the starting rectangle is fully or partially outside of the target rectangle, we
- // need to start the clipping at the edge and then achieve the rest with translation
- // and extending the clip rect from that edge.
- if (appFrame.top > centerY - halfHeight) {
- translationY = (centerY - halfHeight) - appFrame.top;
- translationYCorrection = 0;
- clipStartY = 0;
- cutOff = true;
- }
- if (appFrame.left > centerX - halfWidth) {
- translationX = (centerX - halfWidth) - appFrame.left;
- clipStartX = 0;
- cutOff = true;
- }
- if (appFrame.right < centerX + halfWidth) {
- translationX = (centerX + halfWidth) - appFrame.right;
- clipStartX = appWidth - mTmpRect.width();
- cutOff = true;
- }
- final long duration = calculateClipRevealTransitionDuration(cutOff, translationX,
- translationY, displayFrame);
-
- // Clip third of the from size of launch icon, expand to full width/height
- Animation clipAnimLR = new ClipRectLRAnimation(
- clipStartX, clipStartX + mTmpRect.width(), 0, appWidth);
- clipAnimLR.setInterpolator(mClipHorizontalInterpolator);
- clipAnimLR.setDuration((long) (duration / 2.5f));
-
- TranslateAnimation translate = new TranslateAnimation(translationX, 0, translationY, 0);
- translate.setInterpolator(cutOff ? TOUCH_RESPONSE_INTERPOLATOR
- : mLinearOutSlowInInterpolator);
- translate.setDuration(duration);
-
- Animation clipAnimTB = new ClipRectTBAnimation(
- clipStartY, clipStartY + mTmpRect.height(),
- 0, appHeight,
- translationYCorrection, 0,
- mLinearOutSlowInInterpolator);
- clipAnimTB.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
- clipAnimTB.setDuration(duration);
-
- // Quick fade-in from icon to app window
- final long alphaDuration = duration / 4;
- AlphaAnimation alpha = new AlphaAnimation(0.5f, 1);
- alpha.setDuration(alphaDuration);
- alpha.setInterpolator(mLinearOutSlowInInterpolator);
-
- AnimationSet set = new AnimationSet(false);
- set.addAnimation(clipAnimLR);
- set.addAnimation(clipAnimTB);
- set.addAnimation(translate);
- set.addAnimation(alpha);
- set.setZAdjustment(Animation.ZORDER_TOP);
- set.initialize(appWidth, appHeight, appWidth, appHeight);
- anim = set;
- mLastHadClipReveal = true;
- mLastClipRevealTransitionDuration = duration;
-
- // If the start rect was full inside the target rect (cutOff == false), we don't need
- // to store the translation, because it's only used if cutOff == true.
- mLastClipRevealMaxTranslation = cutOff
- ? Math.max(Math.abs(translationY), Math.abs(translationX)) : 0;
- } else {
- final long duration;
- switch (transit) {
- case TRANSIT_OLD_ACTIVITY_OPEN:
- case TRANSIT_OLD_ACTIVITY_CLOSE:
- duration = mConfigShortAnimTime;
- break;
- default:
- duration = DEFAULT_APP_TRANSITION_DURATION;
- break;
- }
- if (transit == TRANSIT_OLD_WALLPAPER_INTRA_OPEN
- || transit == TRANSIT_OLD_WALLPAPER_INTRA_CLOSE) {
- // If we are on top of the wallpaper, we need an animation that
- // correctly handles the wallpaper staying static behind all of
- // the animated elements. To do this, will just have the existing
- // element fade out.
- anim = new AlphaAnimation(1, 0);
- anim.setDetachWallpaper(true);
- } else {
- // For normal animations, the exiting element just holds in place.
- anim = new AlphaAnimation(1, 1);
- }
- anim.setInterpolator(mDecelerateInterpolator);
- anim.setDuration(duration);
- anim.setFillAfter(true);
- }
- return anim;
- }
-
/**
* Prepares the specified animation with a standard duration, interpolator, etc.
*/
- Animation prepareThumbnailAnimationWithDuration(Animation a, int appWidth, int appHeight,
- long duration, Interpolator interpolator) {
- if (duration > 0) {
- a.setDuration(duration);
- }
- a.setFillAfter(true);
- if (interpolator != null) {
- a.setInterpolator(interpolator);
+ Animation prepareThumbnailAnimationWithDuration(@Nullable Animation a, int appWidth,
+ int appHeight, long duration, Interpolator interpolator) {
+ if (a != null) {
+ if (duration > 0) {
+ a.setDuration(duration);
+ }
+ a.setFillAfter(true);
+ if (interpolator != null) {
+ a.setInterpolator(interpolator);
+ }
+ a.initialize(appWidth, appHeight, appWidth, appHeight);
}
- a.initialize(appWidth, appHeight, appWidth, appHeight);
return a;
}
@@ -1069,8 +703,8 @@ public class AppTransition implements Dump {
}
Animation createCrossProfileAppsThumbnailAnimationLocked(Rect appRect) {
- final Animation animation = loadAnimationRes(
- "android", com.android.internal.R.anim.cross_profile_apps_thumbnail_enter);
+ final Animation animation =
+ mTransitionAnimation.loadCrossProfileAppThumbnailEnterAnimation();
return prepareThumbnailAnimationWithDuration(animation, appRect.width(),
appRect.height(), 0, null);
}
@@ -1203,145 +837,6 @@ public class AppTransition implements Dump {
return TOUCH_RESPONSE_INTERPOLATOR;
}
- /**
- * This alternate animation is created when we are doing a thumbnail transition, for the
- * activity that is leaving, and the activity that is entering.
- */
- Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState,
- int uiMode, int orientation, int transit, Rect containingFrame, Rect contentInsets,
- @Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean freeform,
- WindowContainer container) {
- Animation a;
- final int appWidth = containingFrame.width();
- final int appHeight = containingFrame.height();
- getDefaultNextAppTransitionStartRect(mTmpRect);
- final int thumbWidthI = mTmpRect.width();
- final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
- final int thumbHeightI = mTmpRect.height();
- final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
- final int thumbStartX = mTmpRect.left - containingFrame.left - contentInsets.left;
- final int thumbStartY = mTmpRect.top - containingFrame.top;
-
- switch (thumbTransitState) {
- case THUMBNAIL_TRANSITION_ENTER_SCALE_UP:
- case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
- final boolean scaleUp = thumbTransitState == THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
- if (freeform && scaleUp) {
- a = createAspectScaledThumbnailEnterFreeformAnimationLocked(
- containingFrame, surfaceInsets, container);
- } else if (freeform) {
- a = createAspectScaledThumbnailExitFreeformAnimationLocked(
- containingFrame, surfaceInsets, container);
- } else {
- AnimationSet set = new AnimationSet(true);
-
- // In portrait, we scale to fit the width
- mTmpFromClipRect.set(containingFrame);
- mTmpToClipRect.set(containingFrame);
-
- // Containing frame is in screen space, but we need the clip rect in the
- // app space.
- mTmpFromClipRect.offsetTo(0, 0);
- mTmpToClipRect.offsetTo(0, 0);
-
- // Exclude insets region from the source clip.
- mTmpFromClipRect.inset(contentInsets);
- mNextAppTransitionInsets.set(contentInsets);
-
- if (shouldScaleDownThumbnailTransition(uiMode, orientation)) {
- // We scale the width and clip to the top/left square
- float scale = thumbWidth /
- (appWidth - contentInsets.left - contentInsets.right);
- if (!mGridLayoutRecentsEnabled) {
- int unscaledThumbHeight = (int) (thumbHeight / scale);
- mTmpFromClipRect.bottom = mTmpFromClipRect.top + unscaledThumbHeight;
- }
-
- mNextAppTransitionInsets.set(contentInsets);
-
- Animation scaleAnim = new ScaleAnimation(
- scaleUp ? scale : 1, scaleUp ? 1 : scale,
- scaleUp ? scale : 1, scaleUp ? 1 : scale,
- containingFrame.width() / 2f,
- containingFrame.height() / 2f + contentInsets.top);
- final float targetX = (mTmpRect.left - containingFrame.left);
- final float x = containingFrame.width() / 2f
- - containingFrame.width() / 2f * scale;
- final float targetY = (mTmpRect.top - containingFrame.top);
- float y = containingFrame.height() / 2f
- - containingFrame.height() / 2f * scale;
-
- // During transition may require clipping offset from any top stable insets
- // such as the statusbar height when statusbar is hidden
- if (mLowRamRecentsEnabled && contentInsets.top == 0 && scaleUp) {
- mTmpFromClipRect.top += stableInsets.top;
- y += stableInsets.top;
- }
- final float startX = targetX - x;
- final float startY = targetY - y;
- Animation clipAnim = scaleUp
- ? new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect)
- : new ClipRectAnimation(mTmpToClipRect, mTmpFromClipRect);
- Animation translateAnim = scaleUp
- ? createCurvedMotion(startX, 0, startY - contentInsets.top, 0)
- : createCurvedMotion(0, startX, 0, startY - contentInsets.top);
-
- set.addAnimation(clipAnim);
- set.addAnimation(scaleAnim);
- set.addAnimation(translateAnim);
-
- } else {
- // In landscape, we don't scale at all and only crop
- mTmpFromClipRect.bottom = mTmpFromClipRect.top + thumbHeightI;
- mTmpFromClipRect.right = mTmpFromClipRect.left + thumbWidthI;
-
- Animation clipAnim = scaleUp
- ? new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect)
- : new ClipRectAnimation(mTmpToClipRect, mTmpFromClipRect);
- Animation translateAnim = scaleUp
- ? createCurvedMotion(thumbStartX, 0,
- thumbStartY - contentInsets.top, 0)
- : createCurvedMotion(0, thumbStartX, 0,
- thumbStartY - contentInsets.top);
-
- set.addAnimation(clipAnim);
- set.addAnimation(translateAnim);
- }
- a = set;
- a.setZAdjustment(Animation.ZORDER_TOP);
- }
- break;
- }
- case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
- // Previous app window during the scale up
- if (transit == TRANSIT_OLD_WALLPAPER_INTRA_OPEN) {
- // Fade out the source activity if we are animating to a wallpaper
- // activity.
- a = new AlphaAnimation(1, 0);
- } else {
- a = new AlphaAnimation(1, 1);
- }
- break;
- }
- case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
- // Target app window during the scale down
- if (transit == TRANSIT_OLD_WALLPAPER_INTRA_OPEN) {
- // Fade in the destination activity if we are animating from a wallpaper
- // activity.
- a = new AlphaAnimation(0, 1);
- } else {
- a = new AlphaAnimation(1, 1);
- }
- break;
- }
- default:
- throw new RuntimeException("Invalid thumbnail transition state");
- }
-
- return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight,
- getAspectScaleDuration(), getAspectScaleInterpolator());
- }
-
private Animation createAspectScaledThumbnailEnterFreeformAnimationLocked(Rect frame,
@Nullable Rect surfaceInsets, WindowContainer container) {
getNextAppTransitionStartRect(container, mTmpRect);
@@ -1408,8 +903,8 @@ public class AppTransition implements Dump {
float scaleW = appWidth / thumbWidth;
float scaleH = appHeight / thumbHeight;
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
- computePivot(mTmpRect.left, 1 / scaleW),
- computePivot(mTmpRect.top, 1 / scaleH));
+ TransitionAnimation.computePivot(mTmpRect.left, 1 / scaleW),
+ TransitionAnimation.computePivot(mTmpRect.top, 1 / scaleH));
scale.setInterpolator(mDecelerateInterpolator);
Animation alpha = new AlphaAnimation(1, 0);
@@ -1425,124 +920,13 @@ public class AppTransition implements Dump {
float scaleW = appWidth / thumbWidth;
float scaleH = appHeight / thumbHeight;
a = new ScaleAnimation(scaleW, 1, scaleH, 1,
- computePivot(mTmpRect.left, 1 / scaleW),
- computePivot(mTmpRect.top, 1 / scaleH));
- }
-
- return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
- }
-
- /**
- * This animation is created when we are doing a thumbnail transition, for the activity that is
- * leaving, and the activity that is entering.
- */
- Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, Rect containingFrame,
- int transit, WindowContainer container) {
- final int appWidth = containingFrame.width();
- final int appHeight = containingFrame.height();
- final HardwareBuffer thumbnailHeader = getAppTransitionThumbnailHeader(container);
- Animation a;
- getDefaultNextAppTransitionStartRect(mTmpRect);
- final int thumbWidthI = thumbnailHeader != null ? thumbnailHeader.getWidth() : appWidth;
- final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
- final int thumbHeightI = thumbnailHeader != null ? thumbnailHeader.getHeight() : appHeight;
- final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
-
- switch (thumbTransitState) {
- case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
- // Entering app scales up with the thumbnail
- float scaleW = thumbWidth / appWidth;
- float scaleH = thumbHeight / appHeight;
- a = new ScaleAnimation(scaleW, 1, scaleH, 1,
- computePivot(mTmpRect.left, scaleW),
- computePivot(mTmpRect.top, scaleH));
- break;
- }
- case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
- // Exiting app while the thumbnail is scaling up should fade or stay in place
- if (transit == TRANSIT_OLD_WALLPAPER_INTRA_OPEN) {
- // Fade out while bringing up selected activity. This keeps the
- // current activity from showing through a launching wallpaper
- // activity.
- a = new AlphaAnimation(1, 0);
- } else {
- // noop animation
- a = new AlphaAnimation(1, 1);
- }
- break;
- }
- case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
- // Entering the other app, it should just be visible while we scale the thumbnail
- // down above it
- a = new AlphaAnimation(1, 1);
- break;
- }
- case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
- // Exiting the current app, the app should scale down with the thumbnail
- float scaleW = thumbWidth / appWidth;
- float scaleH = thumbHeight / appHeight;
- Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
- computePivot(mTmpRect.left, scaleW),
- computePivot(mTmpRect.top, scaleH));
-
- Animation alpha = new AlphaAnimation(1, 0);
-
- AnimationSet set = new AnimationSet(true);
- set.addAnimation(scale);
- set.addAnimation(alpha);
- set.setZAdjustment(Animation.ZORDER_TOP);
- a = set;
- break;
- }
- default:
- throw new RuntimeException("Invalid thumbnail transition state");
+ TransitionAnimation.computePivot(mTmpRect.left, 1 / scaleW),
+ TransitionAnimation.computePivot(mTmpRect.top, 1 / scaleH));
}
return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
}
- private Animation createRelaunchAnimation(Rect containingFrame, Rect contentInsets) {
- getDefaultNextAppTransitionStartRect(mTmpFromClipRect);
- final int left = mTmpFromClipRect.left;
- final int top = mTmpFromClipRect.top;
- mTmpFromClipRect.offset(-left, -top);
- // TODO: Isn't that strange that we ignore exact position of the containingFrame?
- mTmpToClipRect.set(0, 0, containingFrame.width(), containingFrame.height());
- AnimationSet set = new AnimationSet(true);
- float fromWidth = mTmpFromClipRect.width();
- float toWidth = mTmpToClipRect.width();
- float fromHeight = mTmpFromClipRect.height();
- // While the window might span the whole display, the actual content will be cropped to the
- // system decoration frame, for example when the window is docked. We need to take into
- // account the visible height when constructing the animation.
- float toHeight = mTmpToClipRect.height() - contentInsets.top - contentInsets.bottom;
- int translateAdjustment = 0;
- if (fromWidth <= toWidth && fromHeight <= toHeight) {
- // The final window is larger in both dimensions than current window (e.g. we are
- // maximizing), so we can simply unclip the new window and there will be no disappearing
- // frame.
- set.addAnimation(new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect));
- } else {
- // The disappearing window has one larger dimension. We need to apply scaling, so the
- // first frame of the entry animation matches the old window.
- set.addAnimation(new ScaleAnimation(fromWidth / toWidth, 1, fromHeight / toHeight, 1));
- // We might not be going exactly full screen, but instead be aligned under the status
- // bar using cropping. We still need to account for the cropped part, which will also
- // be scaled.
- translateAdjustment = (int) (contentInsets.top * fromHeight / toHeight);
- }
-
- // We animate the translation from the old position of the removed window, to the new
- // position of the added window. The latter might not be full screen, for example docked for
- // docked windows.
- TranslateAnimation translate = new TranslateAnimation(left - containingFrame.left,
- 0, top - containingFrame.top - translateAdjustment, 0);
- set.addAnimation(translate);
- set.setDuration(DEFAULT_APP_TRANSITION_DURATION);
- set.setZAdjustment(Animation.ZORDER_TOP);
- return set;
- }
-
/**
* @return true if and only if the first frame of the transition can be skipped, i.e. the first
* frame of the transition doesn't change the visuals on screen, so we can start
@@ -1581,6 +965,7 @@ public class AppTransition implements Dump {
* to the recents thumbnail and hence need to account for the surface being
* bigger.
*/
+ @Nullable
Animation loadAnimation(LayoutParams lp, int transit, boolean enter, int uiMode,
int orientation, Rect frame, Rect displayFrame, Rect insets,
@Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean isVoiceInteraction,
@@ -1592,57 +977,61 @@ public class AppTransition implements Dump {
Animation a;
if (isKeyguardGoingAwayTransitOld(transit) && enter) {
- a = loadKeyguardExitAnimation(transit);
+ a = mTransitionAnimation.loadKeyguardExitAnimation(transit, mNextAppTransitionFlags);
} else if (transit == TRANSIT_OLD_KEYGUARD_OCCLUDE) {
a = null;
} else if (transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE && !enter) {
- a = loadAnimationRes(lp, com.android.internal.R.anim.wallpaper_open_exit);
+ a = mTransitionAnimation.loadKeyguardUnoccludeAnimation(lp);
} else if (transit == TRANSIT_OLD_CRASHING_ACTIVITY_CLOSE) {
a = null;
} else if (isVoiceInteraction && (transit == TRANSIT_OLD_ACTIVITY_OPEN
|| transit == TRANSIT_OLD_TASK_OPEN
|| transit == TRANSIT_OLD_TASK_TO_FRONT)) {
- a = loadAnimationRes(lp, enter
- ? com.android.internal.R.anim.voice_activity_open_enter
- : com.android.internal.R.anim.voice_activity_open_exit);
+ a = mTransitionAnimation.loadVoiceActivityOpenAnimation(lp, enter);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", a,
appTransitionOldToString(transit), enter, Debug.getCallers(3));
} else if (isVoiceInteraction && (transit == TRANSIT_OLD_ACTIVITY_CLOSE
|| transit == TRANSIT_OLD_TASK_CLOSE
|| transit == TRANSIT_OLD_TASK_TO_BACK)) {
- a = loadAnimationRes(lp, enter
- ? com.android.internal.R.anim.voice_activity_close_enter
- : com.android.internal.R.anim.voice_activity_close_exit);
+ a = mTransitionAnimation.loadVoiceActivityExitAnimation(lp, enter);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s", a,
appTransitionOldToString(transit), enter, Debug.getCallers(3));
} else if (transit == TRANSIT_OLD_ACTIVITY_RELAUNCH) {
- a = createRelaunchAnimation(frame, insets);
+ a = mTransitionAnimation.createRelaunchAnimation(frame, insets,
+ mDefaultNextAppTransitionAnimationSpec != null
+ ? mDefaultNextAppTransitionAnimationSpec.rect : null);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation: anim=%s transit=%s Callers=%s", a,
appTransitionOldToString(transit), Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
- a = loadAnimationRes(mNextAppTransitionPackage, enter ?
- mNextAppTransitionEnter : mNextAppTransitionExit);
+ a = mTransitionAnimation.loadAppTransitionAnimation(mNextAppTransitionPackage,
+ enter ? mNextAppTransitionEnter : mNextAppTransitionExit);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM transit=%s "
+ "isEntrance=%b Callers=%s",
a, appTransitionOldToString(transit), enter, Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
- a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
+ a = mTransitionAnimation.loadAppTransitionAnimation(
+ mNextAppTransitionPackage, mNextAppTransitionInPlace);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation: anim=%s nextAppTransition=ANIM_CUSTOM_IN_PLACE "
+ "transit=%s Callers=%s",
a, appTransitionOldToString(transit), Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
- a = createClipRevealAnimationLocked(transit, enter, frame, displayFrame);
+ a = mTransitionAnimation.createClipRevealAnimationLocked(
+ transit, enter, frame, displayFrame,
+ mDefaultNextAppTransitionAnimationSpec != null
+ ? mDefaultNextAppTransitionAnimationSpec.rect : null);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation: anim=%s nextAppTransition=ANIM_CLIP_REVEAL "
+ "transit=%s Callers=%s",
a, appTransitionOldToString(transit), Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
- a = createScaleUpAnimationLocked(transit, enter, frame);
+ a = mTransitionAnimation.createScaleUpAnimationLocked(transit, enter, frame,
+ mDefaultNextAppTransitionAnimationSpec != null
+ ? mDefaultNextAppTransitionAnimationSpec.rect : null);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation: anim=%s nextAppTransition=ANIM_SCALE_UP transit=%s "
+ "isEntrance=%s Callers=%s",
@@ -1651,8 +1040,11 @@ public class AppTransition implements Dump {
mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
mNextAppTransitionScaleUp =
(mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
- a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
- frame, transit, container);
+ final HardwareBuffer thumbnailHeader = getAppTransitionThumbnailHeader(container);
+ a = mTransitionAnimation.createThumbnailEnterExitAnimationLocked(
+ getThumbnailTransitionState(enter), frame, transit, thumbnailHeader,
+ mDefaultNextAppTransitionAnimationSpec != null
+ ? mDefaultNextAppTransitionAnimationSpec.rect : null);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b "
+ "Callers=%s",
@@ -1663,9 +1055,13 @@ public class AppTransition implements Dump {
mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN) {
mNextAppTransitionScaleUp =
(mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP);
- a = createAspectScaledThumbnailEnterExitAnimationLocked(
- getThumbnailTransitionState(enter), uiMode, orientation, transit, frame,
- insets, surfaceInsets, stableInsets, freeform, container);
+ AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(
+ container.hashCode());
+ a = mTransitionAnimation.createAspectScaledThumbnailEnterExitAnimationLocked(
+ getThumbnailTransitionState(enter), orientation, transit, frame,
+ insets, surfaceInsets, stableInsets, freeform, spec != null ? spec.rect : null,
+ mDefaultNextAppTransitionAnimationSpec != null
+ ? mDefaultNextAppTransitionAnimationSpec.rect : null);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b "
+ "Callers=%s",
@@ -1674,8 +1070,7 @@ public class AppTransition implements Dump {
: "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN",
appTransitionOldToString(transit), enter, Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS && enter) {
- a = loadAnimationRes("android",
- com.android.internal.R.anim.task_open_enter_cross_profile_apps);
+ a = mTransitionAnimation.loadCrossProfileAppEnterAnimation();
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: "
+ "anim=%s transit=%s isEntrance=true Callers=%s",
@@ -1758,18 +1153,6 @@ public class AppTransition implements Dump {
return a;
}
- private Animation loadKeyguardExitAnimation(int transit) {
- if ((mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) != 0) {
- return null;
- }
- final boolean toShade =
- (mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0;
- final boolean subtle =
- (mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) != 0;
- return mService.mPolicy.createHiddenByKeyguardExit(
- transit == TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER, toShade, subtle);
- }
-
int getAppRootTaskClipMode() {
return mNextAppTransitionRequests.contains(TRANSIT_RELAUNCH)
|| mNextAppTransitionRequests.contains(TRANSIT_KEYGUARD_GOING_AWAY)
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartCallback.java b/services/core/java/com/android/server/wm/BackgroundActivityStartCallback.java
index 200f207fe50a..eec648dae24a 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartCallback.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartCallback.java
@@ -31,7 +31,8 @@ public interface BackgroundActivityStartCallback {
* Note that if the start was allowed due to a mechanism other than tokens (eg. permission),
* this won't be called.
*
- * This will be called holding the WM lock, don't do anything costly here.
+ * This will be called holding the WM and local lock, don't do anything costly or invoke AM/WM
+ * methods here directly.
*/
boolean isActivityStartAllowed(Collection<IBinder> tokens, int uid, String packageName);
@@ -40,7 +41,8 @@ public interface BackgroundActivityStartCallback {
* #ACTION_CLOSE_SYSTEM_DIALOGS}, presumably to start activities, based on the originating
* tokens {@code tokens} currently associated with potential activity starts.
*
- * This will be called holding the AM and WM lock, don't do anything costly here.
+ * This will be called holding the AM and local lock, don't do anything costly or invoke AM/WM
+ * methods here directly.
*/
boolean canCloseSystemDialogs(Collection<IBinder> tokens, int uid);
}
diff --git a/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
new file mode 100644
index 000000000000..ab1ed67d4cf9
--- /dev/null
+++ b/services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2021 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.wm;
+
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.SystemClock;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.IntArray;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.function.IntPredicate;
+
+/**
+ * A per-process controller to decide whether the process can start activity or foreground service
+ * (especially from background). All methods of this class must be thread safe. The caller does not
+ * need to hold WM lock, e.g. lock contention of WM lock shouldn't happen when starting service.
+ */
+class BackgroundLaunchProcessController {
+ private static final String TAG =
+ TAG_WITH_CLASS_NAME ? "BackgroundLaunchProcessController" : TAG_ATM;
+
+ /** It is {@link ActivityTaskManagerService#hasActiveVisibleWindow(int)}. */
+ private final IntPredicate mUidHasActiveVisibleWindowPredicate;
+
+ private final @Nullable BackgroundActivityStartCallback mBackgroundActivityStartCallback;
+
+ /**
+ * A set of tokens that currently contribute to this process being temporarily allowed
+ * to start activities even if it's not in the foreground. The values of this map are optional
+ * (can be null) and are used to trace back the grant to the notification token mechanism.
+ */
+ @GuardedBy("this")
+ private @Nullable ArrayMap<Binder, IBinder> mBackgroundActivityStartTokens;
+
+ /** Set of UIDs of clients currently bound to this process. */
+ @GuardedBy("this")
+ private @Nullable IntArray mBoundClientUids;
+
+ BackgroundLaunchProcessController(@NonNull IntPredicate uidHasActiveVisibleWindowPredicate,
+ @Nullable BackgroundActivityStartCallback callback) {
+ mUidHasActiveVisibleWindowPredicate = uidHasActiveVisibleWindowPredicate;
+ mBackgroundActivityStartCallback = callback;
+ }
+
+ boolean areBackgroundActivityStartsAllowed(int pid, int uid, String packageName,
+ boolean appSwitchAllowed, boolean isCheckingForFgsStart, boolean hasVisibleActivities,
+ boolean hasBackgroundActivityStartPrivileges, long lastStopAppSwitchesTime,
+ long lastActivityLaunchTime, long lastActivityFinishTime) {
+ // If app switching is not allowed, we ignore all the start activity grace period
+ // exception so apps cannot start itself in onPause() after pressing home button.
+ if (appSwitchAllowed) {
+ // Allow if any activity in the caller has either started or finished very recently, and
+ // it must be started or finished after last stop app switches time.
+ final long now = SystemClock.uptimeMillis();
+ if (now - lastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
+ || now - lastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
+ // If activity is started and finished before stop app switch time, we should not
+ // let app to be able to start background activity even it's in grace period.
+ if (lastActivityLaunchTime > lastStopAppSwitchesTime
+ || lastActivityFinishTime > lastStopAppSwitchesTime) {
+ if (DEBUG_ACTIVITY_STARTS) {
+ Slog.d(TAG, "[Process(" + pid
+ + ")] Activity start allowed: within "
+ + ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period");
+ }
+ return true;
+ }
+ if (DEBUG_ACTIVITY_STARTS) {
+ Slog.d(TAG, "[Process(" + pid + ")] Activity start within "
+ + ACTIVITY_BG_START_GRACE_PERIOD_MS
+ + "ms grace period but also within stop app switch window");
+ }
+
+ }
+ }
+ // Allow if the proc is instrumenting with background activity starts privs.
+ if (hasBackgroundActivityStartPrivileges) {
+ if (DEBUG_ACTIVITY_STARTS) {
+ Slog.d(TAG, "[Process(" + pid
+ + ")] Activity start allowed: process instrumenting with background "
+ + "activity starts privileges");
+ }
+ return true;
+ }
+ // Allow if the caller has an activity in any foreground task.
+ if (appSwitchAllowed && hasVisibleActivities) {
+ if (DEBUG_ACTIVITY_STARTS) {
+ Slog.d(TAG, "[Process(" + pid
+ + ")] Activity start allowed: process has activity in foreground task");
+ }
+ return true;
+ }
+ // Allow if the caller is bound by a UID that's currently foreground.
+ if (isBoundByForegroundUid()) {
+ if (DEBUG_ACTIVITY_STARTS) {
+ Slog.d(TAG, "[Process(" + pid
+ + ")] Activity start allowed: process bound by foreground uid");
+ }
+ return true;
+ }
+ // Allow if the flag was explicitly set.
+ if (isBackgroundStartAllowedByToken(uid, packageName, isCheckingForFgsStart)) {
+ if (DEBUG_ACTIVITY_STARTS) {
+ Slog.d(TAG, "[Process(" + pid
+ + ")] Activity start allowed: process allowed by token");
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * If there are no tokens, we don't allow *by token*. If there are tokens and
+ * isCheckingForFgsStart is false, we ask the callback if the start is allowed for these tokens,
+ * otherwise if there is no callback we allow.
+ */
+ private boolean isBackgroundStartAllowedByToken(int uid, String packageName,
+ boolean isCheckingForFgsStart) {
+ synchronized (this) {
+ if (mBackgroundActivityStartTokens == null
+ || mBackgroundActivityStartTokens.isEmpty()) {
+ return false;
+ }
+ if (isCheckingForFgsStart) {
+ // BG-FGS-start only checks if there is a token.
+ return true;
+ }
+
+ if (mBackgroundActivityStartCallback == null) {
+ // We have tokens but no callback to decide => allow.
+ return true;
+ }
+ // The callback will decide.
+ return mBackgroundActivityStartCallback.isActivityStartAllowed(
+ mBackgroundActivityStartTokens.values(), uid, packageName);
+ }
+ }
+
+ private boolean isBoundByForegroundUid() {
+ synchronized (this) {
+ if (mBoundClientUids != null) {
+ for (int i = mBoundClientUids.size() - 1; i >= 0; i--) {
+ if (mUidHasActiveVisibleWindowPredicate.test(mBoundClientUids.get(i))) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ void setBoundClientUids(ArraySet<Integer> boundClientUids) {
+ synchronized (this) {
+ if (boundClientUids == null || boundClientUids.isEmpty()) {
+ mBoundClientUids = null;
+ return;
+ }
+ if (mBoundClientUids == null) {
+ mBoundClientUids = new IntArray();
+ } else {
+ mBoundClientUids.clear();
+ }
+ for (int i = boundClientUids.size() - 1; i >= 0; i--) {
+ mBoundClientUids.add(boundClientUids.valueAt(i));
+ }
+ }
+ }
+
+ /**
+ * Allows background activity starts using token {@code entity}. Optionally, you can provide
+ * {@code originatingToken} if you have one such originating token, this is useful for tracing
+ * back the grant in the case of the notification token.
+ *
+ * If {@code entity} is already added, this method will update its {@code originatingToken}.
+ */
+ void addOrUpdateAllowBackgroundActivityStartsToken(Binder entity,
+ @Nullable IBinder originatingToken) {
+ synchronized (this) {
+ if (mBackgroundActivityStartTokens == null) {
+ mBackgroundActivityStartTokens = new ArrayMap<>();
+ }
+ mBackgroundActivityStartTokens.put(entity, originatingToken);
+ }
+ }
+
+ /**
+ * Removes token {@code entity} that allowed background activity starts added via {@link
+ * #addOrUpdateAllowBackgroundActivityStartsToken(Binder, IBinder)}.
+ */
+ void removeAllowBackgroundActivityStartsToken(Binder entity) {
+ synchronized (this) {
+ if (mBackgroundActivityStartTokens != null) {
+ mBackgroundActivityStartTokens.remove(entity);
+ }
+ }
+ }
+
+ /**
+ * Returns whether this process is allowed to close system dialogs via a background activity
+ * start token that allows the close system dialogs operation (eg. notification).
+ */
+ boolean canCloseSystemDialogsByToken(int uid) {
+ if (mBackgroundActivityStartCallback == null) {
+ return false;
+ }
+ synchronized (this) {
+ if (mBackgroundActivityStartTokens == null
+ || mBackgroundActivityStartTokens.isEmpty()) {
+ return false;
+ }
+ return mBackgroundActivityStartCallback.canCloseSystemDialogs(
+ mBackgroundActivityStartTokens.values(), uid);
+ }
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ synchronized (this) {
+ if (mBackgroundActivityStartTokens != null
+ && !mBackgroundActivityStartTokens.isEmpty()) {
+ pw.print(prefix);
+ pw.println("Background activity start tokens (token: originating token):");
+ for (int i = mBackgroundActivityStartTokens.size() - 1; i >= 0; i--) {
+ pw.print(prefix);
+ pw.print(" - ");
+ pw.print(mBackgroundActivityStartTokens.keyAt(i));
+ pw.print(": ");
+ pw.println(mBackgroundActivityStartTokens.valueAt(i));
+ }
+ }
+ if (mBoundClientUids != null && mBoundClientUids.size() > 0) {
+ pw.print(prefix);
+ pw.print("BoundClientUids:");
+ pw.println(Arrays.toString(mBoundClientUids.toArray()));
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
deleted file mode 100644
index eee27c72e583..000000000000
--- a/services/core/java/com/android/server/wm/BarController.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import android.annotation.NonNull;
-import android.graphics.Rect;
-
-/**
- * Controls state/behavior specific to a system bar window.
- */
-public class BarController {
- private final int mWindowType;
-
- private final Rect mContentFrame = new Rect();
-
- BarController(int windowType) {
- mWindowType = windowType;
- }
-
- /**
- * Sets the frame within which the bar will display its content.
- *
- * This is used to determine if letterboxes interfere with the display of such content.
- */
- void setContentFrame(Rect frame) {
- mContentFrame.set(frame);
- }
-
- private Rect getContentFrame(@NonNull WindowState win) {
- final Rect rotatedContentFrame = win.mToken.getFixedRotationBarContentFrame(mWindowType);
- return rotatedContentFrame != null ? rotatedContentFrame : mContentFrame;
- }
-
- boolean isLightAppearanceAllowed(WindowState win) {
- if (win == null) {
- return true;
- }
- return !win.isLetterboxedOverlappingWith(getContentFrame(win));
- }
-
- boolean isTransparentAllowed(WindowState win) {
- if (win == null) {
- return true;
- }
- return win.isTransparentBarAllowed(getContentFrame(win));
- }
-}
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index 15483cb90ce2..f075d850c20f 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -462,6 +462,23 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
}
@Override
+ void resolveOverrideConfiguration(Configuration newParentConfiguration) {
+ super.resolveOverrideConfiguration(newParentConfiguration);
+ final Configuration resolvedConfig = getResolvedOverrideConfiguration();
+ final Rect overrideBounds = resolvedConfig.windowConfiguration.getBounds();
+ final Rect overrideAppBounds = resolvedConfig.windowConfiguration.getAppBounds();
+ final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds();
+
+ // If there is no override of appBounds, restrict appBounds to the override bounds.
+ if (!overrideBounds.isEmpty() && (overrideAppBounds == null || overrideAppBounds.isEmpty())
+ && parentAppBounds != null && !parentAppBounds.isEmpty()) {
+ final Rect appBounds = new Rect(overrideBounds);
+ appBounds.intersect(parentAppBounds);
+ resolvedConfig.windowConfiguration.setAppBounds(appBounds);
+ }
+ }
+
+ @Override
boolean isOrganized() {
return mOrganizer != null;
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ece101d2e605..d5d06f9a0033 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -670,8 +670,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// Used in updating override configurations
private final Configuration mTempConfig = new Configuration();
- // Used in performing layout
- private boolean mTmpWindowsBehindIme;
+ // Used in performing layout, to record the insets provided by other windows above the current
+ // window.
+ private InsetsState mTmpAboveInsetsState = new InsetsState();
/**
* Used to prevent recursions when calling
@@ -770,17 +771,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
+ " parentHidden=" + w.isParentWindowHidden());
}
- // Sets mBehindIme for each window. Windows behind IME can get IME insets.
- if (w.mBehindIme != mTmpWindowsBehindIme) {
- w.mBehindIme = mTmpWindowsBehindIme;
- if (getInsetsStateController().getRawInsetsState().getSourceOrDefaultVisibility(
- ITYPE_IME)) {
- // If IME is invisible, behind IME or not doesn't make the insets different.
- mWinInsetsChanged.add(w);
- }
- }
- if (w == mInputMethodWindow) {
- mTmpWindowsBehindIme = true;
+ // Sets mAboveInsets for each window. Windows behind the window providing the insets can
+ // receive the insets.
+ if (!w.mAboveInsetsState.equals(mTmpAboveInsetsState)) {
+ w.mAboveInsetsState.set(mTmpAboveInsetsState);
+ mWinInsetsChanged.add(w);
}
// If this view is GONE, then skip it -- keep the current frame, and let the caller know
@@ -816,8 +811,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
+ " mContainingFrame=" + w.getContainingFrame()
+ " mDisplayFrame=" + w.getDisplayFrame());
}
+ provideInsetsByWindow(w);
};
+ private void provideInsetsByWindow(WindowState w) {
+ for (int i = 0; i < w.mProvidedInsetsSources.size(); i++) {
+ final InsetsSource providedSource = w.mProvidedInsetsSources.valueAt(i);
+ mTmpAboveInsetsState.addSource(providedSource);
+ }
+ }
+
private final Consumer<WindowState> mPerformLayoutAttached = w -> {
if (w.mLayoutAttached) {
if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + w + " mHaveFrame=" + w.mHaveFrame
@@ -4283,14 +4286,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
+ " dh=" + mDisplayInfo.logicalHeight);
}
+ // Used to indicate that we have processed the insets windows. This needs to be after
+ // beginLayoutLw to ensure the raw insets state display related info is initialized.
+ final InsetsState rawInsetsState = getInsetsStateController().getRawInsetsState();
+ mTmpAboveInsetsState = new InsetsState();
+ mTmpAboveInsetsState.setDisplayFrame(rawInsetsState.getDisplayFrame());
+ mTmpAboveInsetsState.setDisplayCutout(rawInsetsState.getDisplayCutout());
+ mTmpAboveInsetsState.mirrorAlwaysVisibleInsetsSources(rawInsetsState);
+
int seq = mLayoutSeq + 1;
if (seq < 0) seq = 0;
mLayoutSeq = seq;
mTmpInitial = initial;
- // Used to indicate that we have processed the IME window.
- mTmpWindowsBehindIme = false;
// First perform layout of any root windows (not attached to another window).
forAllWindows(mPerformLayout, true /* traverseTopToBottom */);
@@ -5485,14 +5494,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
/** Checks whether the given activity is in size compatibility mode and notifies the change. */
void handleActivitySizeCompatModeIfNeeded(ActivityRecord r) {
- if (!r.isState(RESUMED) || r.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
+ final Task organizedTask = r.getOrganizedTask();
+ if (!r.isState(RESUMED) || r.getWindowingMode() != WINDOWING_MODE_FULLSCREEN
+ || organizedTask == null) {
// The callback is only interested in the foreground changes of fullscreen activity.
return;
}
if (!r.inSizeCompatMode()) {
if (mLastCompatModeActivity != null) {
+ // TODO(b/178327644) Remove notifySizeCompatModeActivityChanged
mAtmService.getTaskChangeNotificationController()
.notifySizeCompatModeActivityChanged(mDisplayId, null /* activityToken */);
+ // This will do nothing until SizeCompatModeActivityController is moved to shell
+ organizedTask.onSizeCompatActivityChanged();
}
mLastCompatModeActivity = null;
return;
@@ -5501,8 +5515,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
return;
}
mLastCompatModeActivity = r;
+ // TODO(b/178327644) Remove notifySizeCompatModeActivityChanged
mAtmService.getTaskChangeNotificationController()
.notifySizeCompatModeActivityChanged(mDisplayId, r.appToken);
+ // This will do nothing until SizeCompatModeActivityController is moved to shell
+ organizedTask.onSizeCompatActivityChanged();
}
boolean isUidPresent(int uid) {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index a7db9d624b7e..ed97848aece7 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -42,6 +42,8 @@ import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
@@ -84,6 +86,7 @@ import static android.view.WindowManagerPolicyConstants.ALT_BAR_TOP;
import static android.view.WindowManagerPolicyConstants.ALT_BAR_UNKNOWN;
import static android.view.WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
@@ -303,8 +306,7 @@ public class DisplayPolicy {
private boolean mLastImmersiveMode;
- private final BarController mStatusBarController;
- private final BarController mNavigationBarController;
+ private final SparseArray<Rect> mBarContentFrames = new SparseArray<>();
// The windows we were told about in focusChanged.
private WindowState mFocusedWindow;
@@ -430,8 +432,8 @@ public class DisplayPolicy {
final int displayId = displayContent.getDisplayId();
- mStatusBarController = new BarController(TYPE_STATUS_BAR);
- mNavigationBarController = new BarController(TYPE_NAVIGATION_BAR);
+ mBarContentFrames.put(TYPE_STATUS_BAR, new Rect());
+ mBarContentFrames.put(TYPE_NAVIGATION_BAR, new Rect());
final Resources r = mContext.getResources();
mCarDockEnablesAccelerometer = r.getBoolean(R.bool.config_carDockEnablesAccelerometer);
@@ -1251,11 +1253,6 @@ public class DisplayPolicy {
displayFrames.mDisplayCutoutSafe.top);
}
- @VisibleForTesting
- BarController getStatusBarController() {
- return mStatusBarController;
- }
-
WindowState getStatusBar() {
return mStatusBar != null ? mStatusBar : mStatusBarAlt;
}
@@ -1471,7 +1468,7 @@ public class DisplayPolicy {
mSystemGestures.screenHeight = info.logicalHeight;
}
- private void layoutStatusBar(DisplayFrames displayFrames, Rect simulatedContentFrame) {
+ private void layoutStatusBar(DisplayFrames displayFrames, Rect contentFrame) {
// decide where the status bar goes ahead of time
if (mStatusBar == null) {
return;
@@ -1498,21 +1495,16 @@ public class DisplayPolicy {
statusBarBottom);
}
- // Tell the bar controller where the collapsed status bar content is.
sTmpRect.set(windowFrames.mFrame);
sTmpRect.intersect(displayFrames.mDisplayCutoutSafe);
sTmpRect.top = windowFrames.mFrame.top; // Ignore top display cutout inset
sTmpRect.bottom = statusBarBottom; // Use collapsed status bar size
- if (simulatedContentFrame != null) {
- simulatedContentFrame.set(sTmpRect);
- } else {
- mStatusBarController.setContentFrame(sTmpRect);
- }
+ contentFrame.set(sTmpRect);
}
- private void layoutNavigationBar(DisplayFrames displayFrames, Rect simulatedContentFrame) {
+ private int layoutNavigationBar(DisplayFrames displayFrames, Rect contentFrame) {
if (mNavigationBar == null) {
- return;
+ return NAV_BAR_INVALID;
}
final int uiMode = mDisplayContent.getConfiguration().uiMode;
@@ -1550,17 +1542,12 @@ public class DisplayPolicy {
windowFrames.setFrames(navigationFrame /* parentFrame */,
navigationFrame /* displayFrame */);
mNavigationBar.computeFrameAndUpdateSourceFrame();
- final Rect contentFrame = sTmpRect;
- contentFrame.set(windowFrames.mFrame);
- contentFrame.intersect(displayFrames.mDisplayCutoutSafe);
- if (simulatedContentFrame != null) {
- simulatedContentFrame.set(contentFrame);
- } else {
- mNavigationBarPosition = navBarPosition;
- mNavigationBarController.setContentFrame(contentFrame);
- }
+ sTmpRect.set(windowFrames.mFrame);
+ sTmpRect.intersect(displayFrames.mDisplayCutoutSafe);
+ contentFrame.set(sTmpRect);
if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + navigationFrame);
+ return navBarPosition;
}
private boolean canReceiveInput(WindowState win) {
@@ -1607,11 +1594,12 @@ public class DisplayPolicy {
*/
public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) {
if (win == mNavigationBar) {
- layoutNavigationBar(displayFrames, null /* simulatedContentFrame */);
+ mNavigationBarPosition = layoutNavigationBar(displayFrames,
+ mBarContentFrames.get(TYPE_NAVIGATION_BAR));
return;
}
if ((win == mStatusBar && !canReceiveInput(win))) {
- layoutStatusBar(displayFrames, null /* simulatedContentFrame */);
+ layoutStatusBar(displayFrames, mBarContentFrames.get(TYPE_STATUS_BAR));
return;
}
final WindowManager.LayoutParams attrs = win.getAttrs();
@@ -2620,7 +2608,7 @@ public class DisplayPolicy {
// Otherwise if it's dimming, clear the light flag.
appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
}
- if (!mStatusBarController.isLightAppearanceAllowed(statusColorWin)) {
+ if (!isLightBarAllowed(statusColorWin, TYPE_STATUS_BAR)) {
appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
}
}
@@ -2683,7 +2671,7 @@ public class DisplayPolicy {
// Clear the light flag for dimming window.
appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
}
- if (!mNavigationBarController.isLightAppearanceAllowed(navColorWin)) {
+ if (!isLightBarAllowed(navColorWin, TYPE_NAVIGATION_BAR)) {
appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
}
}
@@ -2693,34 +2681,17 @@ public class DisplayPolicy {
private int updateSystemBarsLw(WindowState win, int disableFlags) {
final boolean dockedRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea()
.isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
- final boolean freeformRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea()
- .isRootTaskVisible(WINDOWING_MODE_FREEFORM);
final boolean resizing = mDisplayContent.getDockedDividerController().isResizing();
// We need to force system bars when the docked root task is visible, when the freeform
// root task is focused but also when we are resizing for the transitions when docked
// root task visibility changes.
mForceShowSystemBars = dockedRootTaskVisible || win.inFreeformWindowingMode() || resizing;
- final boolean forceOpaqueStatusBar = mForceShowSystemBars && !isKeyguardShowing();
-
- final boolean fullscreenDrawsStatusBarBackground =
- drawsStatusBarBackground(mTopFullscreenOpaqueWindowState);
- final boolean dockedDrawsStatusBarBackground =
- drawsStatusBarBackground(mTopDockedOpaqueWindowState);
- final boolean fullscreenDrawsNavBarBackground =
- drawsNavigationBarBackground(mTopFullscreenOpaqueWindowState);
- final boolean dockedDrawsNavigationBarBackground =
- drawsNavigationBarBackground(mTopDockedOpaqueWindowState);
int appearance = APPEARANCE_OPAQUE_NAVIGATION_BARS | APPEARANCE_OPAQUE_STATUS_BARS;
- if (fullscreenDrawsStatusBarBackground && dockedDrawsStatusBarBackground) {
- appearance &= ~APPEARANCE_OPAQUE_STATUS_BARS;
- }
-
- appearance = configureNavBarOpacity(appearance, dockedRootTaskVisible,
- freeformRootTaskVisible, resizing, fullscreenDrawsNavBarBackground,
- dockedDrawsNavigationBarBackground);
+ appearance = configureStatusBarOpacity(appearance);
+ appearance = configureNavBarOpacity(appearance, dockedRootTaskVisible, resizing);
final boolean requestHideNavBar = !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR);
final long now = SystemClock.uptimeMillis();
@@ -2754,10 +2725,36 @@ public class DisplayPolicy {
return appearance;
}
- private boolean drawsBarBackground(WindowState win, BarController controller) {
- if (!controller.isTransparentAllowed(win)) {
- return false;
+ private boolean isLightBarAllowed(WindowState win, int windowType) {
+ if (win == null) {
+ return true;
+ }
+ return !win.isLetterboxedOverlappingWith(getBarContentFrameForWindow(win, windowType));
+ }
+
+ private Rect getBarContentFrameForWindow(WindowState win, int windowType) {
+ final Rect rotatedBarFrame = win.mToken.getFixedRotationBarContentFrame(windowType);
+ return rotatedBarFrame != null ? rotatedBarFrame : mBarContentFrames.get(windowType);
+ }
+
+ /**
+ * @return {@code true} if bar is allowed to be fully transparent when given window is show.
+ *
+ * <p>Prevents showing a transparent bar over a letterboxed activity which can make
+ * notification icons or navigation buttons unreadable due to contrast between letterbox
+ * background and an activity. For instance, this happens when letterbox background is solid
+ * black while activity is white. To resolve this, only semi-transparent bars are allowed to
+ * be drawn over letterboxed activity.
+ */
+ @VisibleForTesting
+ boolean isFullyTransparentAllowed(WindowState win, int windowType) {
+ if (win == null) {
+ return true;
}
+ return win.isFullyTransparentBarAllowed(getBarContentFrameForWindow(win, windowType));
+ }
+
+ private boolean drawsBarBackground(WindowState win) {
if (win == null) {
return true;
}
@@ -2770,12 +2767,23 @@ public class DisplayPolicy {
return forceDrawsSystemBars || drawsSystemBars;
}
- private boolean drawsStatusBarBackground(WindowState win) {
- return drawsBarBackground(win, mStatusBarController);
- }
+ /** @return the current visibility flags with the status bar opacity related flags toggled. */
+ private int configureStatusBarOpacity(int appearance) {
+ final boolean fullscreenDrawsBackground =
+ drawsBarBackground(mTopFullscreenOpaqueWindowState);
+ final boolean dockedDrawsBackground =
+ drawsBarBackground(mTopDockedOpaqueWindowState);
- private boolean drawsNavigationBarBackground(WindowState win) {
- return drawsBarBackground(win, mNavigationBarController);
+ if (fullscreenDrawsBackground && dockedDrawsBackground) {
+ appearance &= ~APPEARANCE_OPAQUE_STATUS_BARS;
+ }
+
+ if (!isFullyTransparentAllowed(mTopFullscreenOpaqueWindowState, TYPE_STATUS_BAR)
+ || !isFullyTransparentAllowed(mTopDockedOpaqueWindowState, TYPE_STATUS_BAR)) {
+ appearance |= APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS;
+ }
+
+ return appearance;
}
/**
@@ -2783,10 +2791,16 @@ public class DisplayPolicy {
* on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}.
*/
private int configureNavBarOpacity(int appearance, boolean dockedRootTaskVisible,
- boolean freeformRootTaskVisible, boolean isDockedDividerResizing,
- boolean fullscreenDrawsBackground, boolean dockedDrawsNavigationBarBackground) {
+ boolean isDockedDividerResizing) {
+ final boolean freeformRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea()
+ .isRootTaskVisible(WINDOWING_MODE_FREEFORM);
+ final boolean fullscreenDrawsBackground =
+ drawsBarBackground(mTopFullscreenOpaqueWindowState);
+ final boolean dockedDrawsBackground =
+ drawsBarBackground(mTopDockedOpaqueWindowState);
+
if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) {
- if (fullscreenDrawsBackground && dockedDrawsNavigationBarBackground) {
+ if (fullscreenDrawsBackground && dockedDrawsBackground) {
appearance = clearNavBarOpaqueFlag(appearance);
} else if (dockedRootTaskVisible) {
appearance = setNavBarOpaqueFlag(appearance);
@@ -2811,6 +2825,11 @@ public class DisplayPolicy {
}
}
+ if (!isFullyTransparentAllowed(mTopFullscreenOpaqueWindowState, TYPE_NAVIGATION_BAR)
+ || !isFullyTransparentAllowed(mTopDockedOpaqueWindowState, TYPE_NAVIGATION_BAR)) {
+ appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
+ }
+
return appearance;
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 1692df6d82cd..c6c7fe083b16 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -151,6 +151,7 @@ class InsetsSourceProvider {
// animate-out as new one animates-in.
mWin.cancelAnimation();
mWin.mPendingPositionChanged = null;
+ mWin.mProvidedInsetsSources.remove(mSource.getType());
}
ProtoLog.d(WM_DEBUG_IME, "InsetsSource setWin %s", win);
mWin = win;
@@ -160,11 +161,14 @@ class InsetsSourceProvider {
setServerVisible(false);
mSource.setFrame(new Rect());
mSource.setVisibleFrame(null);
- } else if (mControllable) {
- mWin.setControllableInsetProvider(this);
- if (mPendingControlTarget != null) {
- updateControlForTarget(mPendingControlTarget, true /* force */);
- mPendingControlTarget = null;
+ } else {
+ mWin.mProvidedInsetsSources.put(mSource.getType(), mSource);
+ if (mControllable) {
+ mWin.setControllableInsetProvider(this);
+ if (mPendingControlTarget != null) {
+ updateControlForTarget(mPendingControlTarget, true /* force */);
+ mPendingControlTarget = null;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 267f67759a24..3ba7b7d96e47 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -104,6 +104,8 @@ class InsetsStateController {
* visible to the target. e.g., the source which represents the target window itself, and the
* IME source when the target is above IME. We also need to exclude certain types of insets
* source for client within specific windowing modes.
+ * This is to get the insets for a window layout on the screen. If the window is not there, use
+ * the {@link #getInsetsForWindowMetrics} to get insets instead.
*
* @param target The window associate with the perspective.
* @return The state stripped of the necessary information.
@@ -117,8 +119,8 @@ class InsetsStateController {
final @InternalInsetsType int type = provider != null
? provider.getSource().getType() : ITYPE_INVALID;
return getInsetsForTarget(type, target.getWindowingMode(), target.isAlwaysOnTop(),
- isAboveIme(target),
- target.getFrozenInsetsState() != null ? target.getFrozenInsetsState() : mState);
+ target.getFrozenInsetsState() != null ? target.getFrozenInsetsState() :
+ target.mAboveInsetsState);
}
InsetsState getInsetsForWindowMetrics(@NonNull WindowManager.LayoutParams attrs) {
@@ -133,19 +135,7 @@ class InsetsStateController {
final @WindowingMode int windowingMode = token != null
? token.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
final boolean alwaysOnTop = token != null && token.isAlwaysOnTop();
- return getInsetsForTarget(type, windowingMode, alwaysOnTop, isAboveIme(token), mState);
- }
-
- private boolean isAboveIme(WindowContainer target) {
- final WindowState imeWindow = mDisplayContent.mInputMethodWindow;
- if (target == null || imeWindow == null) {
- return false;
- }
- if (target instanceof WindowState) {
- final WindowState win = (WindowState) target;
- return win.needsRelativeLayeringToIme() || !win.mBehindIme;
- }
- return false;
+ return getInsetsForTarget(type, windowingMode, alwaysOnTop, mState);
}
private static @InternalInsetsType
@@ -181,10 +171,12 @@ class InsetsStateController {
* @see #getInsetsForWindowMetrics
*/
private InsetsState getInsetsForTarget(@InternalInsetsType int type,
- @WindowingMode int windowingMode, boolean isAlwaysOnTop, boolean aboveIme,
- @NonNull InsetsState state) {
+ @WindowingMode int windowingMode, boolean isAlwaysOnTop, InsetsState state) {
+ boolean stateCopied = false;
+
if (type != ITYPE_INVALID) {
state = new InsetsState(state);
+ stateCopied = true;
state.removeSource(type);
// Navigation bar doesn't get influenced by anything else
@@ -219,23 +211,15 @@ class InsetsStateController {
if (WindowConfiguration.isFloating(windowingMode)
|| (windowingMode == WINDOWING_MODE_MULTI_WINDOW && isAlwaysOnTop)) {
- state = new InsetsState(state);
+ if (!stateCopied) {
+ state = new InsetsState(state);
+ stateCopied = true;
+ }
state.removeSource(ITYPE_STATUS_BAR);
state.removeSource(ITYPE_NAVIGATION_BAR);
state.removeSource(ITYPE_EXTRA_NAVIGATION_BAR);
}
- if (aboveIme) {
- InsetsSource imeSource = state.peekSource(ITYPE_IME);
- if (imeSource != null && imeSource.isVisible()) {
- imeSource = new InsetsSource(imeSource);
- imeSource.setVisible(false);
- imeSource.setFrame(0, 0, 0, 0);
- state = new InsetsState(state);
- state.addSource(imeSource);
- }
- }
-
return state;
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 6a3110f52c91..f3f608bb9070 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3082,6 +3082,20 @@ class Task extends WindowContainer<WindowContainer> {
return parentTask == null ? this : parentTask.getRootTask();
}
+ /** @return the first organized task. */
+ @Nullable
+ Task getOrganizedTask() {
+ if (isOrganized()) {
+ return this;
+ }
+ final WindowContainer parent = getParent();
+ if (parent == null) {
+ return null;
+ }
+ final Task parentTask = parent.asTask();
+ return parentTask == null ? null : parentTask.getOrganizedTask();
+ }
+
// TODO(task-merge): Figure out what's the right thing to do for places that used it.
boolean isRootTask() {
return getRootTask() == this;
@@ -4172,6 +4186,14 @@ class Task extends WindowContainer<WindowContainer> {
info.topActivityInfo = mReuseActivitiesReport.top != null
? mReuseActivitiesReport.top.info
: null;
+ info.topActivityToken = mReuseActivitiesReport.top != null
+ ? mReuseActivitiesReport.top.appToken
+ : null;
+ // Whether the direct top activity is in size compat mode on foreground.
+ info.topActivityInSizeCompat = mReuseActivitiesReport.top != null
+ && mReuseActivitiesReport.top.getOrganizedTask() == this
+ && mReuseActivitiesReport.top.inSizeCompatMode()
+ && mReuseActivitiesReport.top.isState(RESUMED);
info.launchCookies.clear();
info.addLaunchCookie(mLaunchCookie);
forAllActivities(r -> {
@@ -5221,6 +5243,12 @@ class Task extends WindowContainer<WindowContainer> {
}
}
+ /** Called when the top activity in the Root Task enters or exits size compat mode. */
+ void onSizeCompatActivityChanged() {
+ // Trigger TaskInfoChanged to update the size compat restart button.
+ dispatchTaskInfoChangedIfNeeded(true /* force */);
+ }
+
/**
* See {@link WindowContainerTransaction#setBoundsChangeTransaction}. In short this
* transaction will be consumed by the next BASE_APPLICATION window within our hierarchy
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 5676909d021c..8b4d415efcb5 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -24,13 +24,11 @@ import static android.os.IInputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.server.am.ActivityManagerService.MY_PID;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS;
import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MILLIS;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
import static com.android.server.wm.Task.ActivityState.DESTROYED;
@@ -61,8 +59,6 @@ import android.os.IBinder;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
-import android.os.SystemClock;
-import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
@@ -103,10 +99,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
final String mName;
final int mUid;
- // A set of tokens that currently contribute to this process being temporarily allowed
- // to start activities even if it's not in the foreground. The values of this map are optional
- // (can be null) and are used to trace back the grant to the notification token mechanism.
- private final ArrayMap<Binder, IBinder> mBackgroundActivityStartTokens = new ArrayMap<>();
// The process of this application; 0 if none
private volatile int mPid;
// user of process.
@@ -118,6 +110,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
final ArraySet<String> mPkgList = new ArraySet<>();
private final WindowProcessListener mListener;
private final ActivityTaskManagerService mAtm;
+ private final BackgroundLaunchProcessController mBgLaunchController;
// The actual proc... may be null only if 'persistent' is true (in which case we are in the
// process of launching the app)
private IApplicationThread mThread;
@@ -169,8 +162,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
private volatile boolean mPerceptible;
// Set to true when process was launched with a wrapper attached
private volatile boolean mUsingWrapper;
- // Set of UIDs of clients currently bound to this process
- private volatile ArraySet<Integer> mBoundClientUids = new ArraySet<Integer>();
// Thread currently set for VR scheduling
int mVrThreadTid;
@@ -191,10 +182,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
// The most recent top-most activity that was resumed in the process for pre-Q app.
private ActivityRecord mPreQTopResumedActivity = null;
// The last time an activity was launched in the process
- private long mLastActivityLaunchTime;
+ private volatile long mLastActivityLaunchTime;
// The last time an activity was finished in the process while the process participated
// in a visible task
- private long mLastActivityFinishTime;
+ private volatile long mLastActivityFinishTime;
// Last configuration that was reported to the process.
private final Configuration mLastReportedConfiguration = new Configuration();
@@ -227,9 +218,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
/** Whether our process is currently running a {@link IRemoteAnimationRunner} */
private boolean mRunningRemoteAnimation;
- @Nullable
- private final BackgroundActivityStartCallback mBackgroundActivityStartCallback;
-
// The bits used for mActivityStateFlags.
private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16;
private static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17;
@@ -246,8 +234,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
*/
private volatile int mActivityStateFlags = ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
- public WindowProcessController(@NonNull ActivityTaskManagerService atm, ApplicationInfo info,
- String name, int uid, int userId, Object owner,
+ public WindowProcessController(@NonNull ActivityTaskManagerService atm,
+ @NonNull ApplicationInfo info, String name, int uid, int userId, Object owner,
@NonNull WindowProcessListener listener) {
mInfo = info;
mName = name;
@@ -256,7 +244,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
mOwner = owner;
mListener = listener;
mAtm = atm;
- mBackgroundActivityStartCallback = mAtm.getBackgroundActivityStartCallback();
+ mBgLaunchController = new BackgroundLaunchProcessController(
+ atm::hasActiveVisibleWindow, atm.getBackgroundActivityStartCallback());
boolean isSysUiPackage = info.packageName.equals(
mAtm.getSysUiServiceComponentLocked().getPackageName());
@@ -489,162 +478,59 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
}
void setLastActivityFinishTimeIfNeeded(long finishTime) {
- if (finishTime <= mLastActivityFinishTime || !hasActivityInVisibleTask()) {
+ if (finishTime <= mLastActivityFinishTime || !hasVisibleActivities()) {
return;
}
mLastActivityFinishTime = finishTime;
}
/**
- * Allows background activity starts using token {@code entity}. Optionally, you can provide
- * {@code originatingToken} if you have one such originating token, this is useful for tracing
- * back the grant in the case of the notification token.
- *
- * If {@code entity} is already added, this method will update its {@code originatingToken}.
+ * @see BackgroundLaunchProcessController#addOrUpdateAllowBackgroundActivityStartsToken(Binder,
+ * IBinder)
*/
public void addOrUpdateAllowBackgroundActivityStartsToken(Binder entity,
@Nullable IBinder originatingToken) {
- synchronized (mAtm.mGlobalLock) {
- mBackgroundActivityStartTokens.put(entity, originatingToken);
- }
+ mBgLaunchController.addOrUpdateAllowBackgroundActivityStartsToken(entity, originatingToken);
}
- /**
- * Removes token {@code entity} that allowed background activity starts added via {@link
- * #addOrUpdateAllowBackgroundActivityStartsToken(Binder, IBinder)}.
- */
+ /** @see BackgroundLaunchProcessController#removeAllowBackgroundActivityStartsToken(Binder) */
public void removeAllowBackgroundActivityStartsToken(Binder entity) {
- synchronized (mAtm.mGlobalLock) {
- mBackgroundActivityStartTokens.remove(entity);
- }
+ mBgLaunchController.removeAllowBackgroundActivityStartsToken(entity);
}
/**
* Is this WindowProcessController in the state of allowing background FGS start?
*/
+ @HotPath(caller = HotPath.START_SERVICE)
public boolean areBackgroundFgsStartsAllowed() {
- synchronized (mAtm.mGlobalLock) {
- return areBackgroundActivityStartsAllowed(mAtm.getBalAppSwitchesAllowed(), true);
- }
+ return areBackgroundActivityStartsAllowed(mAtm.getBalAppSwitchesAllowed(),
+ true /* isCheckingForFgsStart */);
}
boolean areBackgroundActivityStartsAllowed(boolean appSwitchAllowed) {
- return areBackgroundActivityStartsAllowed(appSwitchAllowed, false);
+ return areBackgroundActivityStartsAllowed(appSwitchAllowed,
+ false /* isCheckingForFgsStart */);
}
- boolean areBackgroundActivityStartsAllowed(boolean appSwitchAllowed,
+ private boolean areBackgroundActivityStartsAllowed(boolean appSwitchAllowed,
boolean isCheckingForFgsStart) {
- // If app switching is not allowed, we ignore all the start activity grace period
- // exception so apps cannot start itself in onPause() after pressing home button.
- if (appSwitchAllowed) {
- // allow if any activity in the caller has either started or finished very recently, and
- // it must be started or finished after last stop app switches time.
- final long now = SystemClock.uptimeMillis();
- if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
- || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
- // if activity is started and finished before stop app switch time, we should not
- // let app to be able to start background activity even it's in grace period.
- if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
- || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
- if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "[WindowProcessController(" + mPid
- + ")] Activity start allowed: within "
- + ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period");
- }
- return true;
- }
- if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start within "
- + ACTIVITY_BG_START_GRACE_PERIOD_MS
- + "ms grace period but also within stop app switch window");
- }
-
- }
- }
- // allow if the proc is instrumenting with background activity starts privs
- if (mInstrumentingWithBackgroundActivityStartPrivileges) {
- if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "[WindowProcessController(" + mPid
- + ")] Activity start allowed: process instrumenting with background "
- + "activity starts privileges");
- }
- return true;
- }
- // allow if the caller has an activity in any foreground task
- if (appSwitchAllowed && hasActivityInVisibleTask()) {
- if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "[WindowProcessController(" + mPid
- + ")] Activity start allowed: process has activity in foreground task");
- }
- return true;
- }
- // allow if the caller is bound by a UID that's currently foreground
- if (isBoundByForegroundUid()) {
- if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "[WindowProcessController(" + mPid
- + ")] Activity start allowed: process bound by foreground uid");
- }
- return true;
- }
- // allow if the flag was explicitly set
- if (isBackgroundStartAllowedByToken(isCheckingForFgsStart)) {
- if (DEBUG_ACTIVITY_STARTS) {
- Slog.d(TAG, "[WindowProcessController(" + mPid
- + ")] Activity start allowed: process allowed by token");
- }
- return true;
- }
- return false;
- }
-
- /**
- * If there are no tokens, we don't allow *by token*. If there are tokens and
- * isCheckingForFgsStart is false, we ask the callback if the start is allowed for these tokens,
- * otherwise if there is no callback we allow.
- */
- private boolean isBackgroundStartAllowedByToken(boolean isCheckingForFgsStart) {
- if (mBackgroundActivityStartTokens.isEmpty()) {
- return false;
- }
-
- if (isCheckingForFgsStart) {
- /// The checking is for BG-FGS-start.
- return true;
- }
-
- if (mBackgroundActivityStartCallback == null) {
- // We have tokens but no callback to decide => allow
- return true;
- }
- // The callback will decide
- return mBackgroundActivityStartCallback.isActivityStartAllowed(
- mBackgroundActivityStartTokens.values(), mInfo.uid, mInfo.packageName);
+ return mBgLaunchController.areBackgroundActivityStartsAllowed(mPid, mUid, mInfo.packageName,
+ appSwitchAllowed, isCheckingForFgsStart, hasVisibleActivities(),
+ mInstrumentingWithBackgroundActivityStartPrivileges,
+ mAtm.getLastStopAppSwitchesTime(),
+ mLastActivityLaunchTime, mLastActivityFinishTime);
}
/**
* Returns whether this process is allowed to close system dialogs via a background activity
* start token that allows the close system dialogs operation (eg. notification).
*/
- public boolean canCloseSystemDialogsByToken() {
- synchronized (mAtm.mGlobalLock) {
- return !mBackgroundActivityStartTokens.isEmpty()
- && mBackgroundActivityStartCallback != null
- && mBackgroundActivityStartCallback.canCloseSystemDialogs(
- mBackgroundActivityStartTokens.values(), mInfo.uid);
- }
- }
-
- private boolean isBoundByForegroundUid() {
- for (int i = mBoundClientUids.size() - 1; i >= 0; --i) {
- if (mAtm.hasActiveVisibleWindow(mBoundClientUids.valueAt(i))) {
- return true;
- }
- }
- return false;
+ boolean canCloseSystemDialogsByToken() {
+ return mBgLaunchController.canCloseSystemDialogsByToken(mUid);
}
public void setBoundClientUids(ArraySet<Integer> boundClientUids) {
- mBoundClientUids = boundClientUids;
+ mBgLaunchController.setBoundClientUids(boundClientUids);
}
/**
@@ -793,20 +679,6 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
return displayArea;
}
- private boolean hasActivityInVisibleTask() {
- for (int i = mActivities.size() - 1; i >= 0; --i) {
- Task task = mActivities.get(i).getTask();
- if (task == null) {
- continue;
- }
- ActivityRecord topActivity = task.getTopNonFinishingActivity();
- if (topActivity != null && topActivity.mVisibleRequested) {
- return true;
- }
- }
- return false;
- }
-
/**
* Update the top resuming activity in process for pre-Q apps, only the top-most visible
* activities are allowed to be resumed per process.
@@ -1701,17 +1573,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
if (mVrThreadTid != 0) {
pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid);
}
- if (mBackgroundActivityStartTokens.size() > 0) {
- pw.print(prefix);
- pw.println("Background activity start tokens (token: originating token):");
- for (int i = 0; i < mBackgroundActivityStartTokens.size(); i++) {
- pw.print(prefix); pw.print(" - ");
- pw.print(mBackgroundActivityStartTokens.keyAt(i));
- pw.print(": ");
- pw.println(mBackgroundActivityStartTokens.valueAt(i));
- }
- }
+ mBgLaunchController.dump(pw, prefix);
}
pw.println(prefix + " Configuration=" + getConfiguration());
pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration());
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 9a7823e35a01..f2be5ffb2ab2 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -212,6 +212,7 @@ import android.os.Trace;
import android.os.WorkSource;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
@@ -647,9 +648,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
boolean mSeamlesslyRotated = false;
/**
- * Indicates if this window is behind IME. Only windows behind IME can get insets from IME.
+ * The insets state of sources provided by windows above the current window.
*/
- boolean mBehindIme = false;
+ InsetsState mAboveInsetsState = new InsetsState();
+
+ /**
+ * The insets sources provided by this window.
+ */
+ ArrayMap<Integer, InsetsSource> mProvidedInsetsSources = new ArrayMap<>();
/**
* Surface insets from the previous call to relayout(), used to track
@@ -3846,11 +3852,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
/**
- * @return {@code true} if bar shown within a given frame is allowed to be transparent
+ * @return {@code true} if bar shown within a given frame is allowed to be fully transparent
* when the current window is displayed.
*/
- boolean isTransparentBarAllowed(Rect frame) {
- return mActivityRecord == null || mActivityRecord.isTransparentBarAllowed(frame);
+ boolean isFullyTransparentBarAllowed(Rect frame) {
+ return mActivityRecord == null || mActivityRecord.isFullyTransparentBarAllowed(frame);
}
public boolean isLetterboxedOverlappingWith(Rect rect) {
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index dc15b0749bb1..5b587e9859d8 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -26,14 +26,14 @@
// Log debug messages about InputDispatcherPolicy
#define DEBUG_INPUT_DISPATCHER_POLICY 0
-
-#include <atomic>
-#include <cinttypes>
-#include <limits.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
+#include <android/os/IInputConstants.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
+#include <limits.h>
+#include <atomic>
+#include <cinttypes>
#include <utils/Log.h>
#include <utils/Looper.h>
@@ -46,6 +46,7 @@
#include <input/SpriteController.h>
#include <ui/Region.h>
+#include <batteryservice/include/batteryservice/BatteryServiceConstants.h>
#include <inputflinger/InputManager.h>
#include <android_os_MessageQueue.h>
@@ -1908,6 +1909,20 @@ static jintArray nativeGetVibratorIds(JNIEnv* env, jclass clazz, jlong ptr, jint
return vibIdArray;
}
+static jint nativeGetBatteryCapacity(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+ std::optional<int32_t> ret = im->getInputManager()->getReader()->getBatteryCapacity(deviceId);
+ return static_cast<jint>(ret.value_or(android::os::IInputConstants::INVALID_BATTERY_CAPACITY));
+}
+
+static jint nativeGetBatteryStatus(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+ std::optional<int32_t> ret = im->getInputManager()->getReader()->getBatteryStatus(deviceId);
+ return static_cast<jint>(ret.value_or(BATTERY_STATUS_UNKNOWN));
+}
+
static void nativeReloadKeyboardLayouts(JNIEnv* /* env */,
jclass /* clazz */, jlong ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -2163,6 +2178,8 @@ static const JNINativeMethod gInputManagerMethods[] = {
{"nativeCancelVibrate", "(JII)V", (void*)nativeCancelVibrate},
{"nativeIsVibrating", "(JI)Z", (void*)nativeIsVibrating},
{"nativeGetVibratorIds", "(JI)[I", (void*)nativeGetVibratorIds},
+ {"nativeGetBatteryCapacity", "(JI)I", (void*)nativeGetBatteryCapacity},
+ {"nativeGetBatteryStatus", "(JI)I", (void*)nativeGetBatteryStatus},
{"nativeReloadKeyboardLayouts", "(J)V", (void*)nativeReloadKeyboardLayouts},
{"nativeReloadDeviceAliases", "(J)V", (void*)nativeReloadDeviceAliases},
{"nativeDump", "(J)Ljava/lang/String;", (void*)nativeDump},
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 544eedf99c9e..da8d82450769 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -97,6 +97,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.RuntimeInit;
+import com.android.internal.policy.AttributeCache;
import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.EmergencyAffordanceManager;
import com.android.internal.util.FrameworkStatsLog;
@@ -341,6 +342,8 @@ public final class SystemServer implements Dumpable {
"com.android.server.contentsuggestions.ContentSuggestionsManagerService";
private static final String SEARCH_UI_MANAGER_SERVICE_CLASS =
"com.android.server.searchui.SearchUiManagerService";
+ private static final String SMARTSPACE_MANAGER_SERVICE_CLASS =
+ "com.android.server.smartspace.SmartspaceManagerService";
private static final String DEVICE_IDLE_CONTROLLER_CLASS =
"com.android.server.DeviceIdleController";
private static final String BLOB_STORE_MANAGER_SERVICE_CLASS =
@@ -359,6 +362,9 @@ public final class SystemServer implements Dumpable {
"com.android.server.ConnectivityServiceInitializer";
private static final String IP_CONNECTIVITY_METRICS_CLASS =
"com.android.server.connectivity.IpConnectivityMetrics";
+ private static final String MEDIA_COMMUNICATION_SERVICE_CLASS =
+ "com.android.server.media.MediaCommunicationService";
+
private static final String ROLE_SERVICE_CLASS = "com.android.role.RoleService";
private static final String GAME_MANAGER_SERVICE_CLASS =
"com.android.server.graphics.GameManagerService$Lifecycle";
@@ -1672,6 +1678,12 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(SEARCH_UI_MANAGER_SERVICE_CLASS);
t.traceEnd();
+ // Smartspace manager service
+ // TODO: add deviceHasConfigString(context, R.string.config_defaultSmartspaceService)
+ t.traceBegin("StartSmartspaceService");
+ mSystemServiceManager.startService(SMARTSPACE_MANAGER_SERVICE_CLASS);
+ t.traceEnd();
+
t.traceBegin("InitConnectivityModuleConnector");
try {
ConnectivityModuleConnector.getInstance().init(context);
@@ -2528,6 +2540,10 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(APP_SEARCH_MANAGER_SERVICE_CLASS);
t.traceEnd();
+ t.traceBegin("StartMediaCommunicationService");
+ mSystemServiceManager.startService(MEDIA_COMMUNICATION_SERVICE_CLASS);
+ t.traceEnd();
+
ConcurrentUtils.waitForFutureNoInterrupt(mBlobStoreServiceStart,
START_BLOB_STORE_SERVICE);
diff --git a/services/people/java/com/android/server/people/data/DataManager.java b/services/people/java/com/android/server/people/data/DataManager.java
index 9a9a17112245..444f9c685a1b 100644
--- a/services/people/java/com/android/server/people/data/DataManager.java
+++ b/services/people/java/com/android/server/people/data/DataManager.java
@@ -264,7 +264,8 @@ public class DataManager {
return new ConversationChannel(shortcutInfo, uid, parentChannel,
parentChannelGroup,
conversationInfo.getLastEventTimestamp(),
- hasActiveNotifications(packageName, userId, shortcutId));
+ hasActiveNotifications(packageName, userId, shortcutId), false,
+ getStatuses(conversationInfo));
}
/** Returns the cached non-customized recent conversations. */
@@ -404,6 +405,10 @@ public class DataManager {
String conversationId) {
ConversationStore cs = getConversationStoreOrThrow(packageName, userId);
ConversationInfo conversationInfo = getConversationInfoOrThrow(cs, conversationId);
+ return getStatuses(conversationInfo);
+ }
+
+ private @NonNull List<ConversationStatus> getStatuses(ConversationInfo conversationInfo) {
Collection<ConversationStatus> statuses = conversationInfo.getStatuses();
if (statuses != null) {
final ArrayList<ConversationStatus> list = new ArrayList<>(statuses.size());
diff --git a/services/smartspace/Android.bp b/services/smartspace/Android.bp
new file mode 100644
index 000000000000..fcf780d4d927
--- /dev/null
+++ b/services/smartspace/Android.bp
@@ -0,0 +1,13 @@
+filegroup {
+ name: "services.smartspace-sources",
+ srcs: ["java/**/*.java"],
+ path: "java",
+ visibility: ["//frameworks/base/services"],
+}
+
+java_library_static {
+ name: "services.smartspace",
+ defaults: ["platform_service_defaults"],
+ srcs: [":services.smartspace-sources"],
+ libs: ["services.core"],
+}
diff --git a/services/smartspace/java/com/android/server/smartspace/RemoteSmartspaceService.java b/services/smartspace/java/com/android/server/smartspace/RemoteSmartspaceService.java
new file mode 100644
index 000000000000..3b5a5a51536e
--- /dev/null
+++ b/services/smartspace/java/com/android/server/smartspace/RemoteSmartspaceService.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2021 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.smartspace;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.service.smartspace.ISmartspaceService;
+import android.text.format.DateUtils;
+
+import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService;
+
+
+/**
+ * Proxy to the {@link android.service.smartspace.SmartspaceService} implementation in another
+ * process.
+ */
+public class RemoteSmartspaceService extends
+ AbstractMultiplePendingRequestsRemoteService<RemoteSmartspaceService,
+ ISmartspaceService> {
+
+ private static final String TAG = "RemoteSmartspaceService";
+
+ private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 2 * DateUtils.SECOND_IN_MILLIS;
+
+ private final RemoteSmartspaceServiceCallbacks mCallback;
+
+ public RemoteSmartspaceService(Context context, String serviceInterface,
+ ComponentName componentName, int userId,
+ RemoteSmartspaceServiceCallbacks callback, boolean bindInstantServiceAllowed,
+ boolean verbose) {
+ super(context, serviceInterface, componentName, userId, callback,
+ context.getMainThreadHandler(),
+ bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0,
+ verbose, /* initialCapacity= */ 1);
+ mCallback = callback;
+ }
+
+ @Override
+ protected ISmartspaceService getServiceInterface(IBinder service) {
+ return ISmartspaceService.Stub.asInterface(service);
+ }
+
+ @Override
+ protected long getTimeoutIdleBindMillis() {
+ return PERMANENT_BOUND_TIMEOUT_MS;
+ }
+
+ @Override
+ protected long getRemoteRequestMillis() {
+ return TIMEOUT_REMOTE_REQUEST_MILLIS;
+ }
+
+ /**
+ * Schedules a request to bind to the remote service.
+ */
+ public void reconnect() {
+ super.scheduleBind();
+ }
+
+ /**
+ * Schedule async request on remote service.
+ */
+ public void scheduleOnResolvedService(@NonNull AsyncRequest<ISmartspaceService> request) {
+ scheduleAsyncRequest(request);
+ }
+
+ /**
+ * Execute async request on remote service immediately instead of sending it to Handler queue.
+ */
+ public void executeOnResolvedService(@NonNull AsyncRequest<ISmartspaceService> request) {
+ executeAsyncRequest(request);
+ }
+
+ /**
+ * Failure callback
+ */
+ public interface RemoteSmartspaceServiceCallbacks
+ extends VultureCallback<RemoteSmartspaceService> {
+
+ /**
+ * Notifies a the failure or timeout of a remote call.
+ */
+ void onFailureOrTimeout(boolean timedOut);
+
+ /**
+ * Notifies change in connected state of the remote service.
+ */
+ void onConnectedStateChanged(boolean connected);
+ }
+
+ @Override // from AbstractRemoteService
+ protected void handleOnConnectedStateChanged(boolean connected) {
+ if (mCallback != null) {
+ mCallback.onConnectedStateChanged(connected);
+ }
+ }
+}
diff --git a/services/smartspace/java/com/android/server/smartspace/SmartspaceManagerService.java b/services/smartspace/java/com/android/server/smartspace/SmartspaceManagerService.java
new file mode 100644
index 000000000000..169b85eb7e06
--- /dev/null
+++ b/services/smartspace/java/com/android/server/smartspace/SmartspaceManagerService.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2021 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.smartspace;
+
+import static android.Manifest.permission.MANAGE_SMARTSPACE;
+import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
+import static android.content.Context.SMARTSPACE_SERVICE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.ActivityManagerInternal;
+import android.app.smartspace.ISmartspaceCallback;
+import android.app.smartspace.ISmartspaceManager;
+import android.app.smartspace.SmartspaceConfig;
+import android.app.smartspace.SmartspaceSessionId;
+import android.app.smartspace.SmartspaceTargetEvent;
+import android.content.Context;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.util.Slog;
+
+import com.android.server.LocalServices;
+import com.android.server.infra.AbstractMasterSystemService;
+import com.android.server.infra.FrameworkResourcesServiceNameResolver;
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+import java.io.FileDescriptor;
+import java.util.function.Consumer;
+
+/**
+ * A service used to return smartspace targets given a query.
+ */
+public class SmartspaceManagerService extends
+ AbstractMasterSystemService<SmartspaceManagerService, SmartspacePerUserService> {
+
+ private static final String TAG = SmartspaceManagerService.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private static final int MAX_TEMP_SERVICE_DURATION_MS = 1_000 * 60 * 2; // 2 minutes
+
+ private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
+
+ public SmartspaceManagerService(Context context) {
+ super(context, new FrameworkResourcesServiceNameResolver(context,
+ com.android.internal.R.string.config_defaultSmartspaceService), null,
+ PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH);
+ mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
+ }
+
+ @Override
+ protected SmartspacePerUserService newServiceLocked(int resolvedUserId, boolean disabled) {
+ return new SmartspacePerUserService(this, mLock, resolvedUserId);
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(SMARTSPACE_SERVICE, new SmartspaceManagerStub());
+ }
+
+ @Override
+ protected void enforceCallingPermissionForManagement() {
+ getContext().enforceCallingPermission(MANAGE_SMARTSPACE, TAG);
+ }
+
+ @Override // from AbstractMasterSystemService
+ protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+ final SmartspacePerUserService service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ service.onPackageUpdatedLocked();
+ }
+ }
+
+ @Override // from AbstractMasterSystemService
+ protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+ final SmartspacePerUserService service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ service.onPackageRestartedLocked();
+ }
+ }
+
+ @Override
+ protected int getMaximumTemporaryServiceDurationMs() {
+ return MAX_TEMP_SERVICE_DURATION_MS;
+ }
+
+ private class SmartspaceManagerStub extends ISmartspaceManager.Stub {
+
+ @Override
+ public void createSmartspaceSession(@NonNull SmartspaceConfig smartspaceConfig,
+ @NonNull SmartspaceSessionId sessionId, @NonNull IBinder token) {
+ runForUserLocked("createSmartspaceSession", sessionId, (service) ->
+ service.onCreateSmartspaceSessionLocked(smartspaceConfig, sessionId, token));
+ }
+
+ @Override
+ public void notifySmartspaceEvent(SmartspaceSessionId sessionId,
+ SmartspaceTargetEvent event) {
+ runForUserLocked("notifySmartspaceEvent", sessionId,
+ (service) -> service.notifySmartspaceEventLocked(sessionId, event));
+ }
+
+ @Override
+ public void requestSmartspaceUpdate(SmartspaceSessionId sessionId) {
+ runForUserLocked("requestSmartspaceUpdate", sessionId,
+ (service) -> service.requestSmartspaceUpdateLocked(sessionId));
+ }
+
+ @Override
+ public void registerSmartspaceUpdates(@NonNull SmartspaceSessionId sessionId,
+ @NonNull ISmartspaceCallback callback) {
+ runForUserLocked("registerSmartspaceUpdates", sessionId,
+ (service) -> service.registerSmartspaceUpdatesLocked(sessionId, callback));
+ }
+
+ @Override
+ public void unregisterSmartspaceUpdates(SmartspaceSessionId sessionId,
+ ISmartspaceCallback callback) {
+ runForUserLocked("unregisterSmartspaceUpdates", sessionId,
+ (service) -> service.unregisterSmartspaceUpdatesLocked(sessionId, callback));
+ }
+
+ @Override
+ public void destroySmartspaceSession(@NonNull SmartspaceSessionId sessionId) {
+ runForUserLocked("destroySmartspaceSession", sessionId,
+ (service) -> service.onDestroyLocked(sessionId));
+ }
+
+ public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+ @Nullable FileDescriptor err,
+ @NonNull String[] args, @Nullable ShellCallback callback,
+ @NonNull ResultReceiver resultReceiver) {
+ new SmartspaceManagerServiceShellCommand(SmartspaceManagerService.this)
+ .exec(this, in, out, err, args, callback, resultReceiver);
+ }
+
+ private void runForUserLocked(@NonNull final String func,
+ @NonNull final SmartspaceSessionId sessionId,
+ @NonNull final Consumer<SmartspacePerUserService> c) {
+ ActivityManagerInternal am = LocalServices.getService(ActivityManagerInternal.class);
+ final int userId = am.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ sessionId.getUserId(), false, ALLOW_NON_FULL, null, null);
+
+ if (DEBUG) {
+ Slog.d(TAG, "runForUserLocked:" + func + " from pid=" + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ }
+ if (!(mServiceNameResolver.isTemporary(userId)
+ || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid()))) {
+
+ String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid();
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
+
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ final SmartspacePerUserService service = getServiceForUserLocked(userId);
+ c.accept(service);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+}
diff --git a/services/smartspace/java/com/android/server/smartspace/SmartspaceManagerServiceShellCommand.java b/services/smartspace/java/com/android/server/smartspace/SmartspaceManagerServiceShellCommand.java
new file mode 100644
index 000000000000..4143418e112e
--- /dev/null
+++ b/services/smartspace/java/com/android/server/smartspace/SmartspaceManagerServiceShellCommand.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2021 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.smartspace;
+
+import android.annotation.NonNull;
+import android.os.ShellCommand;
+
+import java.io.PrintWriter;
+
+/**
+ * The shell command implementation for the SmartspaceManagerService.
+ */
+public class SmartspaceManagerServiceShellCommand extends ShellCommand {
+
+ private static final String TAG =
+ SmartspaceManagerServiceShellCommand.class.getSimpleName();
+
+ private final SmartspaceManagerService mService;
+
+ public SmartspaceManagerServiceShellCommand(@NonNull SmartspaceManagerService service) {
+ mService = service;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+ final PrintWriter pw = getOutPrintWriter();
+ switch (cmd) {
+ case "set": {
+ final String what = getNextArgRequired();
+ switch (what) {
+ case "temporary-service": {
+ final int userId = Integer.parseInt(getNextArgRequired());
+ String serviceName = getNextArg();
+ if (serviceName == null) {
+ mService.resetTemporaryService(userId);
+ pw.println("SmartspaceService temporarily reset. ");
+ return 0;
+ }
+ final int duration = Integer.parseInt(getNextArgRequired());
+ mService.setTemporaryService(userId, serviceName, duration);
+ pw.println("SmartspaceService temporarily set to " + serviceName
+ + " for " + duration + "ms");
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ return 0;
+ }
+
+ @Override
+ public void onHelp() {
+ try (PrintWriter pw = getOutPrintWriter()) {
+ pw.println("SmartspaceManagerService commands:");
+ pw.println(" help");
+ pw.println(" Prints this help text.");
+ pw.println("");
+ pw.println(" set temporary-service USER_ID [COMPONENT_NAME DURATION]");
+ pw.println(" Temporarily (for DURATION ms) changes the service implemtation.");
+ pw.println(" To reset, call with just the USER_ID argument.");
+ pw.println("");
+ }
+ }
+}
diff --git a/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java b/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
new file mode 100644
index 000000000000..db4346830efb
--- /dev/null
+++ b/services/smartspace/java/com/android/server/smartspace/SmartspacePerUserService.java
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2021 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.smartspace;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.AppGlobals;
+import android.app.smartspace.ISmartspaceCallback;
+import android.app.smartspace.SmartspaceConfig;
+import android.app.smartspace.SmartspaceSessionId;
+import android.app.smartspace.SmartspaceTargetEvent;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ServiceInfo;
+import android.os.IBinder;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.service.smartspace.ISmartspaceService;
+import android.service.smartspace.SmartspaceService;
+import android.util.ArrayMap;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.infra.AbstractRemoteService;
+import com.android.server.infra.AbstractPerUserSystemService;
+
+/**
+ * Per-user instance of {@link SmartspaceManagerService}.
+ */
+public class SmartspacePerUserService extends
+ AbstractPerUserSystemService<SmartspacePerUserService, SmartspaceManagerService>
+ implements RemoteSmartspaceService.RemoteSmartspaceServiceCallbacks {
+
+ private static final String TAG = SmartspacePerUserService.class.getSimpleName();
+ @GuardedBy("mLock")
+ private final ArrayMap<SmartspaceSessionId, SmartspaceSessionInfo> mSessionInfos =
+ new ArrayMap<>();
+ @Nullable
+ @GuardedBy("mLock")
+ private RemoteSmartspaceService mRemoteService;
+ /**
+ * When {@code true}, remote service died but service state is kept so it's restored after
+ * the system re-binds to it.
+ */
+ @GuardedBy("mLock")
+ private boolean mZombie;
+
+ protected SmartspacePerUserService(SmartspaceManagerService master,
+ Object lock, int userId) {
+ super(master, lock, userId);
+ }
+
+ @Override // from PerUserSystemService
+ protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent)
+ throws NameNotFoundException {
+
+ ServiceInfo si;
+ try {
+ si = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
+ PackageManager.GET_META_DATA, mUserId);
+ } catch (RemoteException e) {
+ throw new NameNotFoundException("Could not get service for " + serviceComponent);
+ }
+ // TODO(b/177858728): must check that either the service is from a system component,
+ // or it matches a service set by shell cmd (so it can be used on CTS tests and when
+ // OEMs are implementing the real service and also verify the proper permissions
+ return si;
+ }
+
+ @GuardedBy("mLock")
+ @Override // from PerUserSystemService
+ protected boolean updateLocked(boolean disabled) {
+ final boolean enabledChanged = super.updateLocked(disabled);
+ if (enabledChanged) {
+ if (!isEnabledLocked()) {
+ // Clear the remote service for the next call
+ updateRemoteServiceLocked();
+ }
+ }
+ return enabledChanged;
+ }
+
+ /**
+ * Notifies the service of a new smartspace session.
+ */
+ @GuardedBy("mLock")
+ public void onCreateSmartspaceSessionLocked(@NonNull SmartspaceConfig smartspaceConfig,
+ @NonNull SmartspaceSessionId sessionId, @NonNull IBinder token) {
+ final boolean serviceExists = resolveService(sessionId,
+ s -> s.onCreateSmartspaceSession(smartspaceConfig, sessionId));
+
+ if (serviceExists && !mSessionInfos.containsKey(sessionId)) {
+ final SmartspaceSessionInfo sessionInfo = new SmartspaceSessionInfo(
+ sessionId, smartspaceConfig, token, () -> {
+ synchronized (mLock) {
+ onDestroyLocked(sessionId);
+ }
+ });
+ if (sessionInfo.linkToDeath()) {
+ mSessionInfos.put(sessionId, sessionInfo);
+ } else {
+ // destroy the session if calling process is already dead
+ onDestroyLocked(sessionId);
+ }
+ }
+ }
+
+ /**
+ * Records an smartspace event to the service.
+ */
+ @GuardedBy("mLock")
+ public void notifySmartspaceEventLocked(@NonNull SmartspaceSessionId sessionId,
+ @NonNull SmartspaceTargetEvent event) {
+ final SmartspaceSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, s -> s.notifySmartspaceEvent(sessionId, event));
+ }
+
+ /**
+ * Requests the service to return smartspace results of an input query.
+ */
+ @GuardedBy("mLock")
+ public void requestSmartspaceUpdateLocked(@NonNull SmartspaceSessionId sessionId) {
+ final SmartspaceSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId,
+ s -> s.requestSmartspaceUpdate(sessionId));
+ }
+
+ /**
+ * Registers a callback for continuous updates of predicted apps or shortcuts.
+ */
+ @GuardedBy("mLock")
+ public void registerSmartspaceUpdatesLocked(@NonNull SmartspaceSessionId sessionId,
+ @NonNull ISmartspaceCallback callback) {
+ final SmartspaceSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ final boolean serviceExists = resolveService(sessionId,
+ s -> s.registerSmartspaceUpdates(sessionId, callback));
+ if (serviceExists) {
+ sessionInfo.addCallbackLocked(callback);
+ }
+ }
+
+ /**
+ * Unregisters a callback for continuous updates of predicted apps or shortcuts.
+ */
+ @GuardedBy("mLock")
+ public void unregisterSmartspaceUpdatesLocked(@NonNull SmartspaceSessionId sessionId,
+ @NonNull ISmartspaceCallback callback) {
+ final SmartspaceSessionInfo sessionInfo = mSessionInfos.get(sessionId);
+ if (sessionInfo == null) return;
+ final boolean serviceExists = resolveService(sessionId,
+ s -> s.unregisterSmartspaceUpdates(sessionId, callback));
+ if (serviceExists) {
+ sessionInfo.removeCallbackLocked(callback);
+ }
+ }
+
+ /**
+ * Notifies the service of the end of an existing smartspace session.
+ */
+ @GuardedBy("mLock")
+ public void onDestroyLocked(@NonNull SmartspaceSessionId sessionId) {
+ if (isDebug()) {
+ Slog.d(TAG, "onDestroyLocked(): sessionId=" + sessionId);
+ }
+ final SmartspaceSessionInfo sessionInfo = mSessionInfos.remove(sessionId);
+ if (sessionInfo == null) return;
+ resolveService(sessionId, s -> s.onDestroySmartspaceSession(sessionId));
+ sessionInfo.destroy();
+ }
+
+ @Override
+ public void onFailureOrTimeout(boolean timedOut) {
+ if (isDebug()) {
+ Slog.d(TAG, "onFailureOrTimeout(): timed out=" + timedOut);
+ }
+ // Do nothing, we are just proxying to the smartspace ui service
+ }
+
+ @Override
+ public void onConnectedStateChanged(boolean connected) {
+ if (isDebug()) {
+ Slog.d(TAG, "onConnectedStateChanged(): connected=" + connected);
+ }
+ if (connected) {
+ synchronized (mLock) {
+ if (mZombie) {
+ // Validation check - shouldn't happen
+ if (mRemoteService == null) {
+ Slog.w(TAG, "Cannot resurrect sessions because remote service is null");
+ return;
+ }
+ mZombie = false;
+ resurrectSessionsLocked();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onServiceDied(RemoteSmartspaceService service) {
+ if (isDebug()) {
+ Slog.w(TAG, "onServiceDied(): service=" + service);
+ }
+ synchronized (mLock) {
+ mZombie = true;
+ }
+ updateRemoteServiceLocked();
+ }
+
+ @GuardedBy("mLock")
+ private void updateRemoteServiceLocked() {
+ if (mRemoteService != null) {
+ mRemoteService.destroy();
+ mRemoteService = null;
+ }
+ }
+
+ void onPackageUpdatedLocked() {
+ if (isDebug()) {
+ Slog.v(TAG, "onPackageUpdatedLocked()");
+ }
+ destroyAndRebindRemoteService();
+ }
+
+ void onPackageRestartedLocked() {
+ if (isDebug()) {
+ Slog.v(TAG, "onPackageRestartedLocked()");
+ }
+ destroyAndRebindRemoteService();
+ }
+
+ private void destroyAndRebindRemoteService() {
+ if (mRemoteService == null) {
+ return;
+ }
+
+ if (isDebug()) {
+ Slog.d(TAG, "Destroying the old remote service.");
+ }
+ mRemoteService.destroy();
+ mRemoteService = null;
+
+ synchronized (mLock) {
+ mZombie = true;
+ }
+ mRemoteService = getRemoteServiceLocked();
+ if (mRemoteService != null) {
+ if (isDebug()) {
+ Slog.d(TAG, "Rebinding to the new remote service.");
+ }
+ mRemoteService.reconnect();
+ }
+ }
+
+ /**
+ * Called after the remote service connected, it's used to restore state from a 'zombie'
+ * service (i.e., after it died).
+ */
+ private void resurrectSessionsLocked() {
+ final int numSessions = mSessionInfos.size();
+ if (isDebug()) {
+ Slog.d(TAG, "Resurrecting remote service (" + mRemoteService + ") on "
+ + numSessions + " sessions.");
+ }
+
+ for (SmartspaceSessionInfo sessionInfo : mSessionInfos.values()) {
+ sessionInfo.resurrectSessionLocked(this, sessionInfo.mToken);
+ }
+ }
+
+ @GuardedBy("mLock")
+ @Nullable
+ protected boolean resolveService(
+ @NonNull final SmartspaceSessionId sessionId,
+ @NonNull final AbstractRemoteService.AsyncRequest<ISmartspaceService> cb) {
+
+ final RemoteSmartspaceService service = getRemoteServiceLocked();
+ if (service != null) {
+ service.executeOnResolvedService(cb);
+ }
+ return service != null;
+ }
+
+ @GuardedBy("mLock")
+ @Nullable
+ private RemoteSmartspaceService getRemoteServiceLocked() {
+ if (mRemoteService == null) {
+ final String serviceName = getComponentNameLocked();
+ if (serviceName == null) {
+ if (mMaster.verbose) {
+ Slog.v(TAG, "getRemoteServiceLocked(): not set");
+ }
+ return null;
+ }
+ ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName);
+
+ mRemoteService = new RemoteSmartspaceService(getContext(),
+ SmartspaceService.SERVICE_INTERFACE, serviceComponent, mUserId, this,
+ mMaster.isBindInstantServiceAllowed(), mMaster.verbose);
+ }
+
+ return mRemoteService;
+ }
+
+ private static final class SmartspaceSessionInfo {
+ private static final boolean DEBUG = false; // Do not submit with true
+ @NonNull
+ final IBinder mToken;
+ @NonNull
+ final IBinder.DeathRecipient mDeathRecipient;
+ @NonNull
+ private final SmartspaceSessionId mSessionId;
+ @NonNull
+ private final SmartspaceConfig mSmartspaceConfig;
+ private final RemoteCallbackList<ISmartspaceCallback> mCallbacks =
+ new RemoteCallbackList<ISmartspaceCallback>() {
+ @Override
+ public void onCallbackDied(ISmartspaceCallback callback) {
+ if (DEBUG) {
+ Slog.d(TAG, "Binder died for session Id=" + mSessionId
+ + " and callback=" + callback.asBinder());
+ }
+ if (mCallbacks.getRegisteredCallbackCount() == 0) {
+ destroy();
+ }
+ }
+ };
+
+ SmartspaceSessionInfo(
+ @NonNull final SmartspaceSessionId id,
+ @NonNull final SmartspaceConfig context,
+ @NonNull final IBinder token,
+ @NonNull final IBinder.DeathRecipient deathRecipient) {
+ if (DEBUG) {
+ Slog.d(TAG, "Creating SmartspaceSessionInfo for session Id=" + id);
+ }
+ mSessionId = id;
+ mSmartspaceConfig = context;
+ mToken = token;
+ mDeathRecipient = deathRecipient;
+ }
+
+ void addCallbackLocked(ISmartspaceCallback callback) {
+ if (DEBUG) {
+ Slog.d(TAG, "Storing callback for session Id=" + mSessionId
+ + " and callback=" + callback.asBinder());
+ }
+ mCallbacks.register(callback);
+ }
+
+ void removeCallbackLocked(ISmartspaceCallback callback) {
+ if (DEBUG) {
+ Slog.d(TAG, "Removing callback for session Id=" + mSessionId
+ + " and callback=" + callback.asBinder());
+ }
+ mCallbacks.unregister(callback);
+ }
+
+ boolean linkToDeath() {
+ try {
+ mToken.linkToDeath(mDeathRecipient, 0);
+ } catch (RemoteException e) {
+ if (DEBUG) {
+ Slog.w(TAG, "Caller is dead before session can be started, sessionId: "
+ + mSessionId);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ void destroy() {
+ if (DEBUG) {
+ Slog.d(TAG, "Removing all callbacks for session Id=" + mSessionId
+ + " and " + mCallbacks.getRegisteredCallbackCount() + " callbacks.");
+ }
+ if (mToken != null) {
+ mToken.unlinkToDeath(mDeathRecipient, 0);
+ }
+ mCallbacks.kill();
+ }
+
+ void resurrectSessionLocked(SmartspacePerUserService service, IBinder token) {
+ int callbackCount = mCallbacks.getRegisteredCallbackCount();
+ if (DEBUG) {
+ Slog.d(TAG, "Resurrecting remote service (" + service.getRemoteServiceLocked()
+ + ") for session Id=" + mSessionId + " and "
+ + callbackCount + " callbacks.");
+ }
+ service.onCreateSmartspaceSessionLocked(mSmartspaceConfig, mSessionId, token);
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
index 743848c2453c..2932926b0b05 100644
--- a/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/VibratorServiceTest.java
@@ -745,7 +745,8 @@ public class VibratorServiceTest {
private InputDevice createInputDeviceWithVibrator(int id) {
return new InputDevice(id, 0, 0, "name", 0, 0, "description", false, 0, 0,
- null, /* hasVibrator= */ true, false, false, false /* hasSensor */);
+ null, /* hasVibrator= */ true, false, false, false /* hasSensor */,
+ false /* hasBattery */);
}
private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
diff --git a/services/tests/servicestests/src/com/android/server/graphics/fonts/FontCrashDetectorTest.java b/services/tests/servicestests/src/com/android/server/graphics/fonts/FontCrashDetectorTest.java
new file mode 100644
index 000000000000..275e7c7fec04
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/graphics/fonts/FontCrashDetectorTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 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.graphics.fonts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.FileUtils;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class FontCrashDetectorTest {
+
+ private File mCacheDir;
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ mCacheDir = new File(context.getCacheDir(), "UpdatableFontDirTest");
+ FileUtils.deleteContentsAndDir(mCacheDir);
+ mCacheDir.mkdirs();
+ }
+
+ @Test
+ public void detectCrash() throws Exception {
+ // Prepare a marker file.
+ File file = new File(mCacheDir, "detectCrash");
+ assertThat(file.createNewFile()).isTrue();
+
+ FontCrashDetector detector = new FontCrashDetector(file);
+ assertThat(detector.hasCrashed()).isTrue();
+
+ detector.clear();
+ assertThat(detector.hasCrashed()).isFalse();
+ assertThat(file.exists()).isFalse();
+ }
+
+ @Test
+ public void monitorCrash() {
+ File file = new File(mCacheDir, "monitorCrash");
+ FontCrashDetector detector = new FontCrashDetector(file);
+ assertThat(detector.hasCrashed()).isFalse();
+
+ FontCrashDetector.MonitoredBlock block = detector.start();
+ assertThat(file.exists()).isTrue();
+
+ block.close();
+ assertThat(file.exists()).isFalse();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
index d06779048837..833103142ccf 100644
--- a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
+++ b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
@@ -147,6 +147,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dirForPreparation = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dirForPreparation.loadFontFileMap();
assertThat(dirForPreparation.getSystemFontConfig().getLastModifiedTimeMillis())
.isEqualTo(expectedModifiedDate);
installFontFile(dirForPreparation, "foo,1", GOOD_SIGNATURE);
@@ -162,6 +163,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
assertThat(dir.getFontFileMap()).containsKey("foo.ttf");
assertThat(parser.getRevision(dir.getFontFileMap().get("foo.ttf"))).isEqualTo(3);
assertThat(dir.getFontFileMap()).containsKey("bar.ttf");
@@ -177,6 +179,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
assertThat(dir.getFontFileMap()).isEmpty();
}
@@ -187,6 +190,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dirForPreparation = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dirForPreparation.loadFontFileMap();
installFontFile(dirForPreparation, "foo,1", GOOD_SIGNATURE);
installFontFile(dirForPreparation, "bar,2", GOOD_SIGNATURE);
installFontFile(dirForPreparation, "foo,3", GOOD_SIGNATURE);
@@ -199,6 +203,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
assertThat(dir.getFontFileMap()).isEmpty();
// All font dirs (including dir for "bar.ttf") should be deleted.
assertThat(mUpdatableFontFilesDir.list()).hasLength(0);
@@ -211,6 +216,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dirForPreparation = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dirForPreparation.loadFontFileMap();
installFontFile(dirForPreparation, "foo,1", GOOD_SIGNATURE);
installFontFile(dirForPreparation, "bar,2", GOOD_SIGNATURE);
installFontFile(dirForPreparation, "foo,3", GOOD_SIGNATURE);
@@ -224,6 +230,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
assertThat(dir.getFontFileMap()).isEmpty();
// All font dirs (including dir for "bar.ttf") should be deleted.
assertThat(mUpdatableFontFilesDir.list()).hasLength(0);
@@ -236,6 +243,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dirForPreparation = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dirForPreparation.loadFontFileMap();
installFontFile(dirForPreparation, "foo,1", GOOD_SIGNATURE);
installFontFile(dirForPreparation, "bar,2", GOOD_SIGNATURE);
installFontFile(dirForPreparation, "foo,3", GOOD_SIGNATURE);
@@ -250,6 +258,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
// For foo.ttf, preinstalled font (revision 5) should be used.
assertThat(dir.getFontFileMap()).doesNotContainKey("foo.ttf");
// For bar.ttf, updated font (revision 4) should be used.
@@ -268,6 +277,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
new File("/dev/null"));
+ dir.loadFontFileMap();
assertThat(dir.getFontFileMap()).isEmpty();
}
@@ -278,6 +288,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
installFontFile(dir, "test,1", GOOD_SIGNATURE);
assertThat(dir.getFontFileMap()).containsKey("test.ttf");
@@ -295,6 +306,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
installFontFile(dir, "test,1", GOOD_SIGNATURE);
Map<String, File> mapBeforeUpgrade = dir.getFontFileMap();
@@ -313,6 +325,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
installFontFile(dir, "test,2", GOOD_SIGNATURE);
try {
@@ -333,6 +346,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
installFontFile(dir, "foo,1", GOOD_SIGNATURE);
installFontFile(dir, "bar,2", GOOD_SIGNATURE);
@@ -349,6 +363,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
try {
installFontFile(dir, "test,1", "Invalid signature");
@@ -368,6 +383,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
try {
installFontFile(dir, "test,1", GOOD_SIGNATURE);
@@ -398,6 +414,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
readonlyFile);
+ dir.loadFontFileMap();
try {
installFontFile(dir, "test,2", GOOD_SIGNATURE);
@@ -429,6 +446,7 @@ public final class UpdatableFontDirTest {
return 0;
}
}, fakeFsverityUtil, mConfigFile);
+ dir.loadFontFileMap();
try {
installFontFile(dir, "foo,1", GOOD_SIGNATURE);
@@ -456,6 +474,7 @@ public final class UpdatableFontDirTest {
return 0;
}
}, fakeFsverityUtil, mConfigFile);
+ dir.loadFontFileMap();
try {
installFontFile(dir, "foo,1", GOOD_SIGNATURE);
@@ -491,6 +510,7 @@ public final class UpdatableFontDirTest {
UpdatableFontDir dir = new UpdatableFontDir(
mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil,
mConfigFile);
+ dir.loadFontFileMap();
try {
installFontFile(dir, "foo,1", GOOD_SIGNATURE);
diff --git a/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java b/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java
index fba36cb402a0..c28292f03357 100644
--- a/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/WorkTypeConfigTest.java
@@ -18,6 +18,9 @@ package com.android.server.job;
import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_BG;
import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_TOP;
+import static org.junit.Assert.fail;
+
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.provider.DeviceConfig;
import android.util.Pair;
@@ -32,6 +35,7 @@ import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.ArrayList;
import java.util.List;
@RunWith(AndroidJUnit4.class)
@@ -58,42 +62,90 @@ public class WorkTypeConfigTest {
}
private void check(@Nullable DeviceConfig.Properties config,
- int defaultTotal, int defaultMaxBg, int defaultMinBg,
- int expectedTotal, int expectedMaxBg, int expectedMinBg) throws Exception {
+ int defaultTotal,
+ @Nullable Pair<Integer, Integer> defaultTopLimits,
+ @Nullable Pair<Integer, Integer> defaultBgLimits,
+ boolean expectedValid, int expectedTotal,
+ @NonNull Pair<Integer, Integer> expectedTopLimits,
+ @NonNull Pair<Integer, Integer> expectedBgLimits) throws Exception {
resetConfig();
if (config != null) {
DeviceConfig.setProperties(config);
}
- final WorkTypeConfig counts = new WorkTypeConfig("test",
- defaultTotal,
- // defaultMin
- List.of(Pair.create(WORK_TYPE_TOP, defaultTotal - defaultMaxBg),
- Pair.create(WORK_TYPE_BG, defaultMinBg)),
- // defaultMax
- List.of(Pair.create(WORK_TYPE_BG, defaultMaxBg)));
+ List<Pair<Integer, Integer>> defaultMin = new ArrayList<>();
+ List<Pair<Integer, Integer>> defaultMax = new ArrayList<>();
+ Integer val;
+ if (defaultTopLimits != null) {
+ if ((val = defaultTopLimits.first) != null) {
+ defaultMin.add(Pair.create(WORK_TYPE_TOP, val));
+ }
+ if ((val = defaultTopLimits.second) != null) {
+ defaultMax.add(Pair.create(WORK_TYPE_TOP, val));
+ }
+ }
+ if (defaultBgLimits != null) {
+ if ((val = defaultBgLimits.first) != null) {
+ defaultMin.add(Pair.create(WORK_TYPE_BG, val));
+ }
+ if ((val = defaultBgLimits.second) != null) {
+ defaultMax.add(Pair.create(WORK_TYPE_BG, val));
+ }
+ }
+
+ final WorkTypeConfig counts;
+ try {
+ counts = new WorkTypeConfig("test",
+ defaultTotal, defaultMin, defaultMax);
+ if (!expectedValid) {
+ fail("Invalid config successfully created");
+ return;
+ }
+ } catch (IllegalArgumentException e) {
+ if (expectedValid) {
+ throw e;
+ } else {
+ // Success
+ return;
+ }
+ }
counts.update(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER));
Assert.assertEquals(expectedTotal, counts.getMaxTotal());
- Assert.assertEquals(expectedMaxBg, counts.getMax(WORK_TYPE_BG));
- Assert.assertEquals(expectedMinBg, counts.getMinReserved(WORK_TYPE_BG));
+ Assert.assertEquals((int) expectedTopLimits.first, counts.getMinReserved(WORK_TYPE_TOP));
+ Assert.assertEquals((int) expectedTopLimits.second, counts.getMax(WORK_TYPE_TOP));
+ Assert.assertEquals((int) expectedBgLimits.first, counts.getMinReserved(WORK_TYPE_BG));
+ Assert.assertEquals((int) expectedBgLimits.second, counts.getMax(WORK_TYPE_BG));
}
@Test
public void test() throws Exception {
// Tests with various combinations.
- check(null, /*default*/ 5, 1, 0, /*expected*/ 5, 1, 0);
- check(null, /*default*/ 5, 0, 0, /*expected*/ 5, 1, 0);
- check(null, /*default*/ 0, 0, 0, /*expected*/ 1, 1, 0);
- check(null, /*default*/ -1, -1, -1, /*expected*/ 1, 1, 0);
- check(null, /*default*/ 5, 5, 5, /*expected*/ 5, 5, 4);
- check(null, /*default*/ 6, 5, 6, /*expected*/ 6, 5, 5);
- check(null, /*default*/ 4, 5, 6, /*expected*/ 4, 4, 3);
- check(null, /*default*/ 5, 1, 1, /*expected*/ 5, 1, 1);
- check(null, /*default*/ 15, 15, 15, /*expected*/ 15, 15, 14);
- check(null, /*default*/ 16, 16, 16, /*expected*/ 16, 16, 15);
- check(null, /*default*/ 20, 20, 20, /*expected*/ 16, 16, 15);
+ check(null, /*default*/ 5, Pair.create(4, null), Pair.create(0, 1),
+ /*expected*/ true, 5, Pair.create(4, 5), Pair.create(0, 1));
+ check(null, /*default*/ 5, Pair.create(5, null), Pair.create(0, 0),
+ /*expected*/ true, 5, Pair.create(5, 5), Pair.create(0, 1));
+ check(null, /*default*/ 0, Pair.create(5, null), Pair.create(0, 0),
+ /*expected*/ false, 1, Pair.create(1, 1), Pair.create(0, 1));
+ check(null, /*default*/ -1, null, Pair.create(-1, -1),
+ /*expected*/ false, 1, Pair.create(1, 1), Pair.create(0, 1));
+ check(null, /*default*/ 5, null, Pair.create(5, 5),
+ /*expected*/ true, 5, Pair.create(1, 5), Pair.create(4, 5));
+ check(null, /*default*/ 6, Pair.create(1, null), Pair.create(6, 5),
+ /*expected*/ false, 6, Pair.create(1, 6), Pair.create(5, 5));
+ check(null, /*default*/ 4, null, Pair.create(6, 5),
+ /*expected*/ false, 4, Pair.create(1, 4), Pair.create(3, 4));
+ check(null, /*default*/ 5, Pair.create(4, null), Pair.create(1, 1),
+ /*expected*/ true, 5, Pair.create(4, 5), Pair.create(1, 1));
+ check(null, /*default*/ 15, null, Pair.create(15, 15),
+ /*expected*/ true, 15, Pair.create(1, 15), Pair.create(14, 15));
+ check(null, /*default*/ 16, null, Pair.create(16, 16),
+ /*expected*/ true, 16, Pair.create(1, 16), Pair.create(15, 16));
+ check(null, /*default*/ 20, null, Pair.create(20, 20),
+ /*expected*/ false, 16, Pair.create(1, 16), Pair.create(15, 16));
+ check(null, /*default*/ 20, null, Pair.create(16, 16),
+ /*expected*/ true, 16, Pair.create(1, 16), Pair.create(15, 16));
// Test for overriding with a setting string.
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
@@ -101,15 +153,26 @@ public class WorkTypeConfigTest {
.setInt(KEY_MAX_BG, 4)
.setInt(KEY_MIN_BG, 3)
.build(),
- /*default*/ 9, 9, 9, /*expected*/ 5, 4, 3);
+ /*default*/ 9, null, Pair.create(9, 9),
+ /*expected*/ true, 5, Pair.create(1, 5), Pair.create(3, 4));
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
.setInt(KEY_MAX_TOTAL, 5).build(),
- /*default*/ 9, 9, 9, /*expected*/ 5, 5, 4);
+ /*default*/ 9, null, Pair.create(9, 9),
+ /*expected*/ true, 5, Pair.create(1, 5), Pair.create(4, 5));
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
.setInt(KEY_MAX_BG, 4).build(),
- /*default*/ 9, 9, 9, /*expected*/ 9, 4, 4);
+ /*default*/ 9, null, Pair.create(9, 9),
+ /*expected*/ true, 9, Pair.create(1, 9), Pair.create(4, 4));
check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
.setInt(KEY_MIN_BG, 3).build(),
- /*default*/ 9, 9, 9, /*expected*/ 9, 9, 3);
+ /*default*/ 9, null, Pair.create(9, 9),
+ /*expected*/ true, 9, Pair.create(1, 9), Pair.create(3, 9));
+ check(new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_JOB_SCHEDULER)
+ .setInt(KEY_MAX_TOTAL, 20)
+ .setInt(KEY_MAX_BG, 20)
+ .setInt(KEY_MIN_BG, 8)
+ .build(),
+ /*default*/ 9, null, Pair.create(9, 9),
+ /*expected*/ true, 16, Pair.create(1, 16), Pair.create(8, 16));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
index 161d3163c1cf..6e5789686c55 100644
--- a/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/people/data/DataManagerTest.java
@@ -535,8 +535,11 @@ public final class DataManagerTest {
listenerService.onNotificationChannelModified(TEST_PKG_NAME, UserHandle.of(USER_ID_PRIMARY),
mNotificationChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
- assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
- TEST_SHORTCUT_ID)).isNotNull();
+ ConversationChannel result = mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
+ TEST_SHORTCUT_ID);
+ assertThat(result).isNotNull();
+ assertThat(result.hasBirthdayToday()).isFalse();
+ assertThat(result.getStatuses()).isEmpty();
}
@Test
@@ -550,13 +553,15 @@ public final class DataManagerTest {
shortcut.setCached(ShortcutInfo.FLAG_PINNED);
mDataManager.addOrUpdateConversationInfo(shortcut);
assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
- TEST_SHORTCUT_ID)).isNotNull();
+ TEST_SHORTCUT_ID)).isNotNull();
assertThat(mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
TEST_SHORTCUT_ID + "1")).isNull();
NotificationListenerService listenerService =
mDataManager.getNotificationListenerServiceForTesting(USER_ID_PRIMARY);
listenerService.onNotificationPosted(mStatusBarNotification);
+ ConversationStatus cs = new ConversationStatus.Builder("id", ACTIVITY_ANNIVERSARY).build();
+ mDataManager.addOrUpdateStatus(TEST_PKG_NAME, USER_ID_PRIMARY, TEST_SHORTCUT_ID, cs);
ConversationChannel result = mDataManager.getConversation(TEST_PKG_NAME, USER_ID_PRIMARY,
TEST_SHORTCUT_ID);
@@ -568,6 +573,8 @@ public final class DataManagerTest {
result.getParentNotificationChannel().getId());
assertEquals(mStatusBarNotification.getPostTime(), result.getLastEventTimestamp());
assertTrue(result.hasActiveNotifications());
+ assertFalse(result.hasBirthdayToday());
+ assertThat(result.getStatuses()).containsExactly(cs);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
index 28d313b4d4b5..e71c2f5ba8da 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
@@ -294,6 +294,8 @@ public class InputDeviceDelegateTest {
private InputDevice createInputDevice(int id, boolean hasVibrator) {
return new InputDevice(id, 0, 0, "name", 0, 0, "description", false, 0, 0,
- null, hasVibrator, false, false, false /* hasSensor */);
+ null, hasVibrator, false, false, false /* hasSensor */, false /* hasBattery */);
+
+
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
index 5c67db7ef813..91fd7a2ad0c1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
@@ -16,8 +16,8 @@
package com.android.server.wm;
-import static android.content.ActivityInfoProto.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
@@ -50,6 +50,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Binder;
import android.platform.test.annotations.Presubmit;
@@ -408,6 +409,32 @@ public class DisplayAreaTest extends WindowTestsBase {
}
@Test
+ public void testRestrictAppBoundsToOverrideBounds() {
+ final RootDisplayArea root =
+ new DisplayAreaPolicyBuilderTest.SurfacelessDisplayAreaRoot(mWm);
+ final DisplayArea<DisplayArea> da = new DisplayArea<>(mWm, ANY, "Test_DA");
+ root.addChild(da, POSITION_TOP);
+ final Rect displayBounds = new Rect(0, 0, 1800, 2800);
+ final Rect displayAppBounds = new Rect(0, 100, 1800, 2800);
+ final Rect daBounds = new Rect(0, 1400, 1800, 2800);
+ root.setBounds(displayBounds);
+
+ // DA inherit parent app bounds.
+ final Configuration displayConfig = new Configuration();
+ displayConfig.windowConfiguration.setAppBounds(displayAppBounds);
+ root.onRequestedOverrideConfigurationChanged(displayConfig);
+
+ assertEquals(displayAppBounds, da.getConfiguration().windowConfiguration.getAppBounds());
+
+ // Restrict DA appBounds to override Bounds
+ da.setBounds(daBounds);
+
+ final Rect expectedDaAppBounds = new Rect(daBounds);
+ expectedDaAppBounds.intersect(displayAppBounds);
+ assertEquals(expectedDaAppBounds, da.getConfiguration().windowConfiguration.getAppBounds());
+ }
+
+ @Test
public void testGetOrientation() {
final DisplayArea.Tokens area = new DisplayArea.Tokens(mWm, ABOVE_TASKS, "test");
final WindowToken token = createWindowToken(TYPE_APPLICATION_OVERLAY);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index 82ffa765cc27..37fb0e930acc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -123,6 +123,15 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
updateDisplayFrames();
}
+ void addWindowWithRawInsetsState(WindowState win) {
+ addWindow(win);
+ // Without mPerformLayout in display content, the window cannot see any insets. Override the
+ // insets state with the global one.
+ final InsetsState insetsState =
+ win.getDisplayContent().getInsetsStateController().getRawInsetsState();
+ win.mAboveInsetsState = insetsState;
+ }
+
public void setRotation(int rotation, boolean includingWindows) {
mRotation = rotation;
updateDisplayFrames();
@@ -272,7 +281,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
@Test
public void layoutWindowLw_fitStatusBars() {
mWindow.mAttrs.setFitInsetsTypes(Type.statusBars());
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -283,7 +292,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
@Test
public void layoutWindowLw_fitNavigationBars() {
mWindow.mAttrs.setFitInsetsTypes(Type.navigationBars());
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -294,7 +303,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
@Test
public void layoutWindowLw_fitAllSides() {
mWindow.mAttrs.setFitInsetsSides(Side.all());
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -305,7 +314,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
@Test
public void layoutWindowLw_fitTopOnly() {
mWindow.mAttrs.setFitInsetsSides(Side.TOP);
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -315,11 +324,12 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
@Test
public void layoutWindowLw_fitInsetsIgnoringVisibility() {
- final InsetsState state = mWindow.getInsetsState();
+ final InsetsState state =
+ mDisplayContent.getInsetsStateController().getRawInsetsState();
state.getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
state.getSource(InsetsState.ITYPE_NAVIGATION_BAR).setVisible(false);
mWindow.mAttrs.setFitInsetsIgnoringVisibility(true);
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -329,11 +339,12 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
@Test
public void layoutWindowLw_fitInsetsNotIgnoringVisibility() {
- final InsetsState state = mWindow.getInsetsState();
+ final InsetsState state =
+ mDisplayContent.getInsetsStateController().getRawInsetsState();
state.getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
state.getSource(InsetsState.ITYPE_NAVIGATION_BAR).setVisible(false);
mWindow.mAttrs.setFitInsetsIgnoringVisibility(false);
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -349,8 +360,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
state.getSource(InsetsState.ITYPE_IME).setFrame(
0, DISPLAY_HEIGHT - IME_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT);
mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
- mWindow.mBehindIme = true;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -364,7 +374,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.setFitInsetsTypes(Type.displayCutout());
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -379,7 +389,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -395,7 +405,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -411,7 +421,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -427,7 +437,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -442,7 +452,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -457,11 +467,12 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
- mWindow.getInsetsState().getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
+ mDisplayContent.getInsetsStateController().getRawInsetsState()
+ .getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
final InsetsState requestedState = new InsetsState();
requestedState.getSource(ITYPE_STATUS_BAR).setVisible(false);
mWindow.updateRequestedVisibility(requestedState);
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -476,12 +487,13 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
- mWindow.getInsetsState().getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
+ mDisplayContent.getInsetsStateController().getRawInsetsState()
+ .getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
final InsetsState requestedState = new InsetsState();
requestedState.getSource(ITYPE_STATUS_BAR).setVisible(false);
mWindow.updateRequestedVisibility(requestedState);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -497,7 +509,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -513,7 +525,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -529,7 +541,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -545,7 +557,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY;
mWindow.mAttrs.width = DISPLAY_WIDTH;
mWindow.mAttrs.height = DISPLAY_HEIGHT;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -562,7 +574,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -576,7 +588,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
mWindow.mAttrs.flags =
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -592,7 +604,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -608,7 +620,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -624,7 +636,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
@@ -638,7 +650,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_NOTHING;
- addWindow(mWindow);
+ addWindowWithRawInsetsState(mWindow);
final int forwardedInsetBottom = 50;
mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom));
@@ -776,9 +788,13 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
public void testFixedRotationInsetsSourceFrame() {
doReturn((mDisplayContent.getRotation() + 1) % 4).when(mDisplayContent)
.rotationForActivityInDifferentOrientation(eq(mWindow.mActivityRecord));
- final Rect frame = mWindow.getInsetsState().getSource(ITYPE_STATUS_BAR).getFrame();
+ mWindow.mAboveInsetsState.addSource(mDisplayContent.getInsetsStateController()
+ .getRawInsetsState().peekSource(ITYPE_STATUS_BAR));
+ final Rect frame = mDisplayPolicy.getInsetsPolicy().getInsetsForWindow(mWindow)
+ .getSource(ITYPE_STATUS_BAR).getFrame();
mDisplayContent.rotateInDifferentOrientationIfNeeded(mWindow.mActivityRecord);
- final Rect rotatedFrame = mWindow.getInsetsState().getSource(ITYPE_STATUS_BAR).getFrame();
+ final Rect rotatedFrame = mDisplayPolicy.getInsetsPolicy().getInsetsForWindow(mWindow)
+ .getSource(ITYPE_STATUS_BAR).getFrame();
assertEquals(DISPLAY_WIDTH, frame.width());
assertEquals(DISPLAY_HEIGHT, rotatedFrame.width());
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 77537a9de6be..499507e969cf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -300,6 +300,7 @@ public class DisplayPolicyTests extends WindowTestsBase {
displayPolicy.addWindowLw(mNavBarWindow, mNavBarWindow.mAttrs);
mNavBarWindow.getControllableInsetProvider().setServerVisible(true);
final InsetsState state = mDisplayContent.getInsetsStateController().getRawInsetsState();
+ mImeWindow.mAboveInsetsState = state;
mDisplayContent.mDisplayFrames = new DisplayFrames(mDisplayContent.getDisplayId(),
state, displayInfo, null /* displayCutout */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
index e6f24da3e7b9..f91c9d0e9853 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DualDisplayAreaGroupPolicyTest.java
@@ -16,7 +16,7 @@
package com.android.server.wm;
-import static android.content.ActivityInfoProto.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index e0fd3796f2aa..bf3ed692dc8e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -45,6 +45,7 @@ import static org.mockito.Mockito.verify;
import android.app.StatusBarManager;
import android.platform.test.annotations.Presubmit;
+import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
@@ -272,7 +273,6 @@ public class InsetsPolicyTest extends WindowTestsBase {
final WindowState navBar = addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar");
navBar.setHasSurface(true);
navBar.getControllableInsetProvider().setServerVisible(true);
-
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
doNothing().when(policy).startAnimation(anyBoolean(), any());
@@ -337,11 +337,14 @@ public class InsetsPolicyTest extends WindowTestsBase {
@UseTestDisplay(addWindows = W_ACTIVITY)
@Test
public void testAbortTransientBars_bothCanBeAborted_appGetsBothRealControls() {
- addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
- .getControllableInsetProvider().getSource().setVisible(false);
- addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
- .getControllableInsetProvider().getSource().setVisible(false);
-
+ final InsetsSource statusBarSource = addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
+ .getControllableInsetProvider().getSource();
+ final InsetsSource navBarSource = addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar")
+ .getControllableInsetProvider().getSource();
+ statusBarSource.setVisible(false);
+ navBarSource.setVisible(false);
+ mAppWindow.mAboveInsetsState.addSource(navBarSource);
+ mAppWindow.mAboveInsetsState.addSource(statusBarSource);
final InsetsPolicy policy = spy(mDisplayContent.getInsetsPolicy());
doNothing().when(policy).startAnimation(anyBoolean(), any());
policy.updateBarControlTarget(mAppWindow);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 276643847712..2107ab1eeeea 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -59,25 +59,6 @@ import org.junit.runner.RunWith;
public class InsetsStateControllerTest extends WindowTestsBase {
@Test
- public void testStripForDispatch_notOwn() {
- final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
- final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- getController().getSourceProvider(ITYPE_STATUS_BAR).setWindow(statusBar, null, null);
- statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR));
- assertNotNull(getController().getInsetsForWindow(app).peekSource(ITYPE_STATUS_BAR));
- }
-
- @Test
- public void testStripForDispatch_own() {
- final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
- mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
- .setWindow(statusBar, null, null);
- statusBar.setControllableInsetProvider(getController().getSourceProvider(ITYPE_STATUS_BAR));
- final InsetsState state = getController().getInsetsForWindow(statusBar);
- assertNull(state.peekSource(ITYPE_STATUS_BAR));
- }
-
- @Test
public void testStripForDispatch_navBar() {
final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
@@ -142,14 +123,15 @@ public class InsetsStateControllerTest extends WindowTestsBase {
getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
final WindowState app1 = createWindow(null, TYPE_APPLICATION, "app1");
- app1.mBehindIme = true;
-
final WindowState app2 = createWindow(null, TYPE_APPLICATION, "app2");
- app2.mBehindIme = false;
+
+ app1.mAboveInsetsState.addSource(getController().getRawInsetsState().getSource(ITYPE_IME));
getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
- assertFalse(getController().getInsetsForWindow(app2).getSource(ITYPE_IME).isVisible());
- assertTrue(getController().getInsetsForWindow(app1).getSource(ITYPE_IME).isVisible());
+ assertFalse(getController().getInsetsForWindow(app2).getSource(ITYPE_IME)
+ .isVisible());
+ assertTrue(getController().getInsetsForWindow(app1).getSource(ITYPE_IME)
+ .isVisible());
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@@ -158,7 +140,8 @@ public class InsetsStateControllerTest extends WindowTestsBase {
getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- app.mBehindIme = true;
+ app.mAboveInsetsState.getSource(ITYPE_IME).setVisible(true);
+ app.mAboveInsetsState.getSource(ITYPE_IME).setFrame(mImeWindow.getFrame());
getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
assertTrue(getController().getInsetsForWindow(app).getSource(ITYPE_IME).isVisible());
@@ -170,10 +153,10 @@ public class InsetsStateControllerTest extends WindowTestsBase {
getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
- app.mBehindIme = false;
getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
- assertFalse(getController().getInsetsForWindow(app).getSource(ITYPE_IME).isVisible());
+ assertFalse(getController().getInsetsForWindow(app).getSource(ITYPE_IME)
+ .isVisible());
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@@ -210,7 +193,8 @@ public class InsetsStateControllerTest extends WindowTestsBase {
// app won't get visible IME insets while above IME even when IME is visible.
assertTrue(getController().getRawInsetsState().getSourceOrDefaultVisibility(ITYPE_IME));
- assertFalse(getController().getInsetsForWindow(app).getSource(ITYPE_IME).isVisible());
+ assertFalse(getController().getInsetsForWindow(app).getSource(ITYPE_IME)
+ .isVisible());
// Reset invocation counter.
clearInvocations(app);
@@ -219,6 +203,8 @@ public class InsetsStateControllerTest extends WindowTestsBase {
app.mAttrs.flags &= ~FLAG_NOT_FOCUSABLE;
mDisplayContent.computeImeTarget(true);
mDisplayContent.applySurfaceChangesTransaction();
+ app.mAboveInsetsState.getSource(ITYPE_IME).setVisible(true);
+ app.mAboveInsetsState.getSource(ITYPE_IME).setFrame(mImeWindow.getFrame());
// Make sure app got notified.
verify(app, atLeast(1)).notifyInsetsChanged();
@@ -234,6 +220,8 @@ public class InsetsStateControllerTest extends WindowTestsBase {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
final WindowState child = createWindow(app, TYPE_APPLICATION, "child");
+ app.mAboveInsetsState.set(getController().getRawInsetsState());
+ child.mAboveInsetsState.set(getController().getRawInsetsState());
child.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM;
mDisplayContent.computeImeTarget(true);
@@ -242,7 +230,8 @@ public class InsetsStateControllerTest extends WindowTestsBase {
getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
assertTrue(getController().getInsetsForWindow(app).getSource(ITYPE_IME).isVisible());
- assertFalse(getController().getInsetsForWindow(child).getSource(ITYPE_IME).isVisible());
+ assertFalse(getController().getInsetsForWindow(child).getSource(ITYPE_IME)
+ .isVisible());
}
@UseTestDisplay(addWindows = W_INPUT_METHOD)
@@ -252,6 +241,7 @@ public class InsetsStateControllerTest extends WindowTestsBase {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
final WindowState child = createWindow(app, TYPE_APPLICATION, "child");
+ app.mAboveInsetsState.addSource(getController().getRawInsetsState().peekSource(ITYPE_IME));
child.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
child.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
@@ -261,7 +251,8 @@ public class InsetsStateControllerTest extends WindowTestsBase {
getController().getRawInsetsState().setSourceVisible(ITYPE_IME, true);
assertTrue(getController().getInsetsForWindow(app).getSource(ITYPE_IME).isVisible());
- assertFalse(getController().getInsetsForWindow(child).getSource(ITYPE_IME).isVisible());
+ assertFalse(getController().getInsetsForWindow(child).getSource(ITYPE_IME)
+ .isVisible());
}
@Test
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 942e1c91989c..bbd89b8d0173 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -26,6 +26,7 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -480,10 +481,13 @@ public class SizeCompatTests extends WindowTestsBase {
/**
* Ensures that {@link TaskStackListener} can receive callback about the activity in size
* compatibility mode.
+ *
+ * TODO(b/178327644) Remove after update DC#handleActivitySizeCompatModeIfNeeded
*/
@Test
public void testHandleActivitySizeCompatMode() {
setUpDisplaySizeWithApp(1000, 2000);
+ doReturn(true).when(mTask).isOrganized();
ActivityRecord activity = mActivity;
activity.setState(Task.ActivityState.RESUMED, "testHandleActivitySizeCompatMode");
prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
@@ -520,6 +524,46 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(null, compatTokens.get(0));
}
+ /**
+ * Ensures that {@link TaskOrganizerController} can receive callback about the activity in size
+ * compatibility mode.
+ */
+ @Test
+ public void testHandleActivitySizeCompatModeChanged() {
+ setUpDisplaySizeWithApp(1000, 2000);
+ doReturn(true).when(mTask).isOrganized();
+ ActivityRecord activity = mActivity;
+ activity.setState(Task.ActivityState.RESUMED, "testHandleActivitySizeCompatModeChanged");
+ prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT);
+ assertFitted();
+
+ // Resize the display so that the activity exercises size-compat mode.
+ resizeDisplay(mTask.mDisplayContent, 1000, 2500);
+
+ // Expect the exact token when the activity is in size compatibility mode.
+ verify(mTask).onSizeCompatActivityChanged();
+ ActivityManager.RunningTaskInfo taskInfo = mTask.getTaskInfo();
+
+ assertEquals(mActivity.appToken, taskInfo.topActivityToken);
+ assertTrue(taskInfo.topActivityInSizeCompat);
+
+ // Make the activity resizable again by restarting it
+ clearInvocations(mTask);
+ activity.info.resizeMode = RESIZE_MODE_RESIZEABLE;
+ activity.mVisibleRequested = true;
+ activity.restartProcessIfVisible();
+ // The full lifecycle isn't hooked up so manually set state to resumed
+ activity.setState(Task.ActivityState.RESUMED, "testHandleActivitySizeCompatModeChanged");
+ mTask.mDisplayContent.handleActivitySizeCompatModeIfNeeded(activity);
+
+ // Expect null token when switching to non-size-compat mode activity.
+ verify(mTask).onSizeCompatActivityChanged();
+ taskInfo = mTask.getTaskInfo();
+
+ assertEquals(mActivity.appToken, taskInfo.topActivityToken);
+ assertFalse(taskInfo.topActivityInSizeCompat);
+ }
+
@Test
public void testShouldUseSizeCompatModeOnResizableTask() {
setUpDisplaySizeWithApp(1000, 2500);
@@ -602,12 +646,11 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(new Rect(mActivity.getBounds().left, 0, dh - mActivity.getBounds().right, 0),
mActivity.getLetterboxInsets());
- final BarController statusBarController =
- mActivity.mDisplayContent.getDisplayPolicy().getStatusBarController();
+ final DisplayPolicy displayPolicy = mActivity.mDisplayContent.getDisplayPolicy();
// The activity doesn't fill the display, so the letterbox of the rotated activity is
// overlapped with the rotated content frame of status bar. Hence the status bar shouldn't
// be transparent.
- assertFalse(statusBarController.isTransparentAllowed(w));
+ assertFalse(displayPolicy.isFullyTransparentAllowed(w, TYPE_STATUS_BAR));
// Make the activity fill the display.
prepareUnresizable(mActivity, 10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE);
@@ -617,7 +660,7 @@ public class SizeCompatTests extends WindowTestsBase {
// The letterbox should only cover the notch area, so status bar can be transparent.
assertEquals(new Rect(notchHeight, 0, 0, 0), mActivity.getLetterboxInsets());
- assertTrue(statusBarController.isTransparentAllowed(w));
+ assertTrue(displayPolicy.isFullyTransparentAllowed(w, TYPE_STATUS_BAR));
}
@Test
@@ -977,9 +1020,9 @@ public class SizeCompatTests extends WindowTestsBase {
displayPolicy.onConfigurationChanged();
final TestWindowToken token = createTestWindowToken(
- WindowManager.LayoutParams.TYPE_STATUS_BAR, displayContent);
+ TYPE_STATUS_BAR, displayContent);
final WindowManager.LayoutParams attrs =
- new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_STATUS_BAR);
+ new WindowManager.LayoutParams(TYPE_STATUS_BAR);
attrs.gravity = android.view.Gravity.TOP;
attrs.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index 1607f013ee81..a1f89ec75784 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -275,7 +275,7 @@ public class WindowFrameTests extends WindowTestsBase {
imeSource.setFrame(imeFrame);
imeSource.setVisible(true);
w.updateRequestedVisibility(state);
- w.mBehindIme = true;
+ w.mAboveInsetsState.addSource(imeSource);
// With no insets or system decor all the frames incoming from PhoneWindowManager
// are identical.
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 37983b442425..77fca3d2fdeb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -42,6 +42,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
+import static com.android.server.wm.Task.ActivityState.RESUMED;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.android.server.wm.WindowContainer.SYNC_STATE_READY;
@@ -55,6 +56,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
@@ -1244,6 +1246,54 @@ public class WindowOrganizerTests extends WindowTestsBase {
assertEquals(splitPrimaryRootTask, activity.getRootTask());
}
+ @Test
+ public void testSizeCompatModeChangedOnFirstOrganizedTask() throws RemoteException {
+ final ITaskOrganizer organizer = registerMockOrganizer();
+ final Task rootTask = createStack();
+ final Task task = createTask(rootTask);
+ final ActivityRecord activity = createActivityRecord(rootTask.mDisplayContent, task);
+ final ArgumentCaptor<RunningTaskInfo> infoCaptor =
+ ArgumentCaptor.forClass(RunningTaskInfo.class);
+
+ assertTrue(rootTask.isOrganized());
+
+ spyOn(activity);
+ doReturn(true).when(activity).inSizeCompatMode();
+ doReturn(true).when(activity).isState(RESUMED);
+
+ // Ensure task info show top activity in size compat.
+ rootTask.onSizeCompatActivityChanged();
+ mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
+ verify(organizer).onTaskInfoChanged(infoCaptor.capture());
+ RunningTaskInfo info = infoCaptor.getValue();
+ assertEquals(rootTask.mTaskId, info.taskId);
+ assertEquals(activity.appToken, info.topActivityToken);
+ assertTrue(info.topActivityInSizeCompat);
+
+ // Ensure task info show top activity that is not in foreground as not in size compat.
+ clearInvocations(organizer);
+ doReturn(false).when(activity).isState(RESUMED);
+ rootTask.onSizeCompatActivityChanged();
+ mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
+ verify(organizer).onTaskInfoChanged(infoCaptor.capture());
+ info = infoCaptor.getValue();
+ assertEquals(rootTask.mTaskId, info.taskId);
+ assertEquals(activity.appToken, info.topActivityToken);
+ assertFalse(info.topActivityInSizeCompat);
+
+ // Ensure task info show non size compat top activity as not in size compat.
+ clearInvocations(organizer);
+ doReturn(true).when(activity).isState(RESUMED);
+ doReturn(false).when(activity).inSizeCompatMode();
+ rootTask.onSizeCompatActivityChanged();
+ mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
+ verify(organizer).onTaskInfoChanged(infoCaptor.capture());
+ info = infoCaptor.getValue();
+ assertEquals(rootTask.mTaskId, info.taskId);
+ assertEquals(activity.appToken, info.topActivityToken);
+ assertFalse(info.topActivityInSizeCompat);
+ }
+
/**
* Verifies that task vanished is called for a specific task.
*/
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index c85991d8f3b2..8b604a32c512 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -88,8 +88,8 @@ import android.view.WindowManager.DisplayImePolicy;
import android.window.ITaskOrganizer;
import android.window.StartingWindowInfo;
+import com.android.internal.policy.AttributeCache;
import com.android.internal.util.ArrayUtils;
-import com.android.server.AttributeCache;
import org.junit.Before;
import org.junit.BeforeClass;
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 3815326b6886..0cb1255c6830 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -79,7 +79,6 @@ import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import com.android.internal.annotations.VisibleForTesting;
@@ -111,6 +110,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
/**
* A service that collects, aggregates, and persists application usage data.
@@ -162,7 +162,7 @@ public class UsageStatsService extends SystemService implements
ShortcutServiceInternal mShortcutServiceInternal;
private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>();
- private final SparseBooleanArray mUserUnlockedStates = new SparseBooleanArray();
+ private final CopyOnWriteArraySet<Integer> mUserUnlockedStates = new CopyOnWriteArraySet<>();
private final SparseIntArray mUidToKernelCounter = new SparseIntArray();
int mUsageSource;
@@ -333,7 +333,7 @@ public class UsageStatsService extends SystemService implements
synchronized (mLock) {
// User was started but never unlocked so no need to report a user stopped event
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
persistPendingEventsLocked(userId);
return;
}
@@ -346,7 +346,7 @@ public class UsageStatsService extends SystemService implements
if (userService != null) {
userService.userStopped();
}
- mUserUnlockedStates.put(userId, false);
+ mUserUnlockedStates.remove(userId);
mUserState.put(userId, null); // release the service (mainly for GC)
}
}
@@ -360,6 +360,11 @@ public class UsageStatsService extends SystemService implements
UsageStatsIdleService.scheduleUpdateMappingsJob(getContext());
}
synchronized (mLock) {
+ // This should be safe to add this early. Other than reportEventOrAddToQueue, every
+ // other user grabs the lock before accessing
+ // mUserUnlockedStates. reportEventOrAddToQueue does not depend on anything other than
+ // mUserUnlockedStates, and the lock will protect the handler.
+ mUserUnlockedStates.add(userId);
// Create a user unlocked event to report
final Event unlockEvent = new Event(USER_UNLOCKED, SystemClock.elapsedRealtime());
unlockEvent.mPackage = Event.DEVICE_EVENT_PACKAGE_NAME;
@@ -377,7 +382,6 @@ public class UsageStatsService extends SystemService implements
initializeUserUsageStatsServiceLocked(userId, System.currentTimeMillis(),
installedPackages);
- mUserUnlockedStates.put(userId, true);
final UserUsageStatsService userService = getUserUsageStatsServiceLocked(userId);
if (userService == null) {
Slog.i(TAG, "Attempted to unlock stopped or removed user " + userId);
@@ -780,12 +784,11 @@ public class UsageStatsService extends SystemService implements
}
private void reportEventOrAddToQueue(int userId, Event event) {
+ if (mUserUnlockedStates.contains(userId)) {
+ mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
+ return;
+ }
synchronized (mLock) {
- if (mUserUnlockedStates.get(userId)) {
- mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
- return;
- }
-
LinkedList<Event> events = mReportedEvents.get(userId);
if (events == null) {
events = new LinkedList<>();
@@ -823,7 +826,7 @@ public class UsageStatsService extends SystemService implements
synchronized (mLock) {
// This should never be called directly when the user is locked
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
Slog.wtf(TAG, "Failed to report event for locked user " + userId
+ " (" + event.mPackage + "/" + event.mClass
+ " eventType:" + event.mEventType
@@ -1006,7 +1009,7 @@ public class UsageStatsService extends SystemService implements
final int tokenRemoved;
synchronized (mLock) {
final long timeRemoved = System.currentTimeMillis();
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
// If user is not unlocked and a package is removed for them, we will handle it
// when the user service is initialized and package manager is queried.
return;
@@ -1030,7 +1033,7 @@ public class UsageStatsService extends SystemService implements
*/
private boolean pruneUninstalledPackagesData(int userId) {
synchronized (mLock) {
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
return false; // user is no longer unlocked
}
@@ -1050,7 +1053,7 @@ public class UsageStatsService extends SystemService implements
// fetch the installed packages outside the lock so it doesn't block package manager.
final HashMap<String, Long> installedPkgs = getInstalledPackages(UserHandle.USER_SYSTEM);
synchronized (mLock) {
- if (!mUserUnlockedStates.get(UserHandle.USER_SYSTEM)) {
+ if (!mUserUnlockedStates.contains(UserHandle.USER_SYSTEM)) {
return false; // user is no longer unlocked
}
@@ -1069,7 +1072,7 @@ public class UsageStatsService extends SystemService implements
List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime,
boolean obfuscateInstantApps) {
synchronized (mLock) {
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
Slog.w(TAG, "Failed to query usage stats for locked user " + userId);
return null;
}
@@ -1103,7 +1106,7 @@ public class UsageStatsService extends SystemService implements
List<ConfigurationStats> queryConfigurationStats(int userId, int bucketType, long beginTime,
long endTime) {
synchronized (mLock) {
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
Slog.w(TAG, "Failed to query configuration stats for locked user " + userId);
return null;
}
@@ -1122,7 +1125,7 @@ public class UsageStatsService extends SystemService implements
List<EventStats> queryEventStats(int userId, int bucketType, long beginTime,
long endTime) {
synchronized (mLock) {
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
Slog.w(TAG, "Failed to query event stats for locked user " + userId);
return null;
}
@@ -1140,7 +1143,7 @@ public class UsageStatsService extends SystemService implements
*/
UsageEvents queryEvents(int userId, long beginTime, long endTime, int flags) {
synchronized (mLock) {
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
Slog.w(TAG, "Failed to query events for locked user " + userId);
return null;
}
@@ -1159,7 +1162,7 @@ public class UsageStatsService extends SystemService implements
UsageEvents queryEventsForPackage(int userId, long beginTime, long endTime,
String packageName, boolean includeTaskRoot) {
synchronized (mLock) {
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
Slog.w(TAG, "Failed to query package events for locked user " + userId);
return null;
}
@@ -1203,7 +1206,7 @@ public class UsageStatsService extends SystemService implements
final int userCount = mUserState.size();
for (int i = 0; i < userCount; i++) {
final int userId = mUserState.keyAt(i);
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
persistPendingEventsLocked(userId);
continue;
}
@@ -1261,7 +1264,7 @@ public class UsageStatsService extends SystemService implements
final int numUsers = mUserState.size();
for (int user = 0; user < numUsers; user++) {
final int userId = mUserState.keyAt(user);
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
continue;
}
ipw.println("user=" + userId);
@@ -1288,7 +1291,7 @@ public class UsageStatsService extends SystemService implements
final int numUsers = mUserState.size();
for (int user = 0; user < numUsers; user++) {
final int userId = mUserState.keyAt(user);
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
continue;
}
ipw.println("user=" + userId);
@@ -1344,7 +1347,7 @@ public class UsageStatsService extends SystemService implements
idpw.printPair("user", userId);
idpw.println();
idpw.increaseIndent();
- if (mUserUnlockedStates.get(userId)) {
+ if (mUserUnlockedStates.contains(userId)) {
if (checkin) {
mUserState.valueAt(i).checkin(idpw);
} else {
@@ -1382,7 +1385,7 @@ public class UsageStatsService extends SystemService implements
ipw.println("the specified user does not exist.");
return UserHandle.USER_NULL;
}
- if (!mUserUnlockedStates.get(userId)) {
+ if (!mUserUnlockedStates.contains(userId)) {
ipw.println("the specified user is currently in a locked state.");
return UserHandle.USER_NULL;
}
@@ -2250,12 +2253,11 @@ public class UsageStatsService extends SystemService implements
@Override
public byte[] getBackupPayload(int user, String key) {
+ if (!mUserUnlockedStates.contains(user)) {
+ Slog.w(TAG, "Failed to get backup payload for locked user " + user);
+ return null;
+ }
synchronized (mLock) {
- if (!mUserUnlockedStates.get(user)) {
- Slog.w(TAG, "Failed to get backup payload for locked user " + user);
- return null;
- }
-
// Check to ensure that only user 0's data is b/r for now
// Note: if backup and restore is enabled for users other than the system user, the
// #onUserUnlocked logic, specifically when the update mappings job is scheduled via
@@ -2275,7 +2277,7 @@ public class UsageStatsService extends SystemService implements
@Override
public void applyRestoredPayload(int user, String key, byte[] payload) {
synchronized (mLock) {
- if (!mUserUnlockedStates.get(user)) {
+ if (!mUserUnlockedStates.contains(user)) {
Slog.w(TAG, "Failed to apply restored payload for locked user " + user);
return;
}
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 1faae42f054b..a9dae898fc9f 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -138,6 +138,8 @@ public final class ImsCallProfile implements Parcelable {
* Indicates if the session is for a conference call or not. If not defined, should be
* considered {@code false}.
* Boolean extra properties - {@code true} / {@code false}.
+ *
+ * This extra is set on an instance of {@link ImsCallProfile} via {@link #setCallExtraBoolean}.
* @hide
*/
@SystemApi
@@ -174,6 +176,8 @@ public final class ImsCallProfile implements Parcelable {
* Indicates if the session can be extended to a conference call. If not defined, should be
* considered {@code false}.
* Boolean extra properties - {@code true} / {@code false}.
+ *
+ * This extra is set on an instance of {@link ImsCallProfile} via {@link #setCallExtraBoolean}.
* @hide
*/
@SystemApi
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index ee6c36ca6b76..d17415a7354a 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2356,6 +2356,21 @@ interface ITelephony {
int removeContactFromEab(int subId, String contacts);
/**
+ * Get the EAB contact from the EAB database.
+ */
+ String getContactFromEab(String contact);
+
+ /*
+ * Check whether the device supports RCS User Capability Exchange or not.
+ */
+ boolean getDeviceUceEnabled();
+
+ /*
+ * Set the device supports RCS User Capability Exchange.
+ */
+ void setDeviceUceEnabled(boolean isEnabled);
+
+ /**
* Set a SignalStrengthUpdateRequest to receive notification when Signal Strength breach the
* specified thresholds.
*/
diff --git a/tests/FlickerTests/TEST_MAPPING b/tests/FlickerTests/TEST_MAPPING
deleted file mode 100644
index db251b907caa..000000000000
--- a/tests/FlickerTests/TEST_MAPPING
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "postsubmit": [
- // Run tests on real device
- {
- "name": "FlickerTests",
- "keywords": ["primary-device"]
- },
- // Also run the tests in the cloud
- {
- "name": "FlickerTests"
- }
- ]
-} \ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index 1d69fe40cb9f..b5fd4a50ae66 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.helpers.SimpleAppHelper
@@ -56,18 +55,16 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class CloseAppBackButtonTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = SimpleAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation, repetitions = 5)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation, repetitions = 5) { configuration ->
withTestName { buildTestTag("closeAppBackButton", configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index f1d08c216f47..584e4b16fab7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.helpers.SimpleAppHelper
@@ -55,18 +54,16 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class CloseAppHomeButtonTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = SimpleAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation, repetitions = 5)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation, repetitions = 5) { configuration ->
withTestName { buildTestTag("closeAppHomeButton", configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
index d3eefd06fec1..fde97ba8b4df 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
@@ -21,7 +21,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
@@ -55,18 +54,16 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 178015460)
class CloseImeAutoOpenWindowToAppTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
- return FlickerTestRunnerFactory(instrumentation, repetitions = 5)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation, repetitions = 5) { configuration ->
val testApp = ImeAppAutoFocusHelper(instrumentation,
configuration.startRotation)
withTestName { buildTestTag("imeToAppAutoOpen", configuration) }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index f5bb8e1bfb14..ab7c08f7902b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
@@ -53,18 +52,16 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class CloseImeAutoOpenWindowToHomeTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
- return FlickerTestRunnerFactory(instrumentation, repetitions = 5)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation, repetitions = 5) { configuration ->
val testApp = ImeAppAutoFocusHelper(instrumentation,
configuration.startRotation)
withTestName {
@@ -114,7 +111,8 @@ class CloseImeAutoOpenWindowToHomeTest(
enabled = !configuration.startRotation.isRotated())
statusBarLayerIsAlwaysVisible(
enabled = !configuration.startRotation.isRotated())
- visibleLayersShownMoreThanOneConsecutiveEntry(listOf(IME_WINDOW_TITLE))
+ visibleLayersShownMoreThanOneConsecutiveEntry(listOf(IME_WINDOW_TITLE),
+ enabled = !configuration.startRotation.isRotated())
imeLayerBecomesInvisible()
imeAppLayerBecomesInvisible(testApp)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
index a3631926e3e8..0503cce0fbb1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
@@ -21,7 +21,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.helpers.ImeAppHelper
@@ -54,10 +53,8 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 178015460)
class CloseImeWindowToAppTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@@ -65,8 +62,8 @@ class CloseImeWindowToAppTest(
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = ImeAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation, repetitions = 5)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation, repetitions = 5) { configuration ->
withTestName { buildTestTag("imeToApp", configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index f474ec2c389c..9cb075b8a0bd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -21,7 +21,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.helpers.ImeAppHelper
@@ -54,18 +53,16 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 178015460)
class CloseImeWindowToHomeTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = ImeAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation, repetitions = 5)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation, repetitions = 5) { configuration ->
withTestName { buildTestTag("imeToHome", configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
index ff07398305bc..13c6cd7e6e18 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
@@ -21,7 +21,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.helpers.ImeAppHelper
@@ -57,18 +56,16 @@ import org.junit.runners.Parameterized
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FlakyTest(bugId = 178015460)
class OpenImeWindowTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = ImeAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation, repetitions = 5)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation, repetitions = 5) { configuration ->
withTestName { buildTestTag("openIme", configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
index d2d5960879ec..6cc64dfd8836 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
@@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
@@ -58,18 +57,16 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class ReOpenImeWindowTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testAppComponentName = ActivityOptions.IME_ACTIVITY_AUTO_FOCUS_COMPONENT_NAME
- return FlickerTestRunnerFactory(instrumentation, repetitions = 1)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation, repetitions = 1) { configuration ->
val testApp = ImeAppAutoFocusHelper(instrumentation,
configuration.startRotation)
withTestName { buildTestTag("reOpenImeAutoFocus", configuration) }
@@ -90,7 +87,6 @@ class ReOpenImeWindowTest(
transitions {
device.reopenAppFromOverview()
wmHelper.waitImeWindowShown()
- // wmHelper.waitForFullScreenApp(testAppComponentName)
}
teardown {
test {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index cf259876c409..010ebf2c2788 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.endRotation
@@ -57,18 +56,16 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class OpenAppColdTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = SimpleAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation) { configuration ->
withTestName { buildTestTag("openAppCold", testApp, configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index c957b3ff2d4a..5e08921c2253 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.endRotation
@@ -58,18 +57,16 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class OpenAppFromOverviewTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = SimpleAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation, repetitions = 5)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation, repetitions = 5) { configuration ->
withTestName { buildTestTag("openAppFromOverview", configuration) }
repeat { configuration.repetitions }
setup {
@@ -118,7 +115,7 @@ class OpenAppFromOverviewTest(
navBarLayerIsAlwaysVisible(
enabled = Surface.ROTATION_0 == configuration.endRotation)
visibleLayersShownMoreThanOneConsecutiveEntry(
- enabled = Surface.ROTATION_0 == configuration.endRotation)
+ enabled = false)
appLayerReplacesWallpaperLayer(testApp.`package`)
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index fd99be273dda..092cd4d2dad6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit
import android.view.Surface
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.endRotation
@@ -56,19 +55,15 @@ import org.junit.runners.Parameterized
@RequiresDevice
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class OpenAppWarmTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+class OpenAppWarmTest(testSpec: FlickerTestRunnerFactory.TestSpec) : FlickerTestRunner(testSpec) {
companion object {
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): List<Array<Any>> {
val instrumentation = InstrumentationRegistry.getInstrumentation()
val testApp = SimpleAppHelper(instrumentation)
- return FlickerTestRunnerFactory(instrumentation)
- .buildTest { configuration ->
+ return FlickerTestRunnerFactory.getInstance()
+ .buildTest(instrumentation) { configuration ->
withTestName { buildTestTag("openAppWarm", testApp, configuration) }
repeat { configuration.repetitions }
setup {
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index fe3ab041aa0b..1c44b21c0f9a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -20,7 +20,6 @@ import android.os.Bundle
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.dsl.FlickerBuilder
@@ -54,10 +53,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class ChangeAppRotationTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object : RotationTransition(InstrumentationRegistry.getInstrumentation()) {
override val testApp: StandardAppHelper
get() = SimpleAppHelper(instrumentation)
@@ -66,7 +63,7 @@ class ChangeAppRotationTest(
private const val SCREENSHOT_LAYER = "RotationLayer"
- @Parameterized.Parameters(name = "{0}")
+ @Parameterized.Parameters(name = "{0}1}")
@JvmStatic
fun getParams(): Collection<Array<Any>> {
val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
@@ -119,8 +116,8 @@ class ChangeAppRotationTest(
}
}
- return FlickerTestRunnerFactory(instrumentation, repetitions = 5)
- .buildRotationTest(transition, testSpec)
+ return FlickerTestRunnerFactory.getInstance()
+ .buildRotationTest(instrumentation, transition, testSpec, repetitions = 5)
}
}
} \ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index e25c734b22c6..f04131b64cd4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -20,7 +20,6 @@ import android.os.Bundle
import android.platform.test.annotations.Presubmit
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.server.wm.flicker.Flicker
import com.android.server.wm.flicker.FlickerTestRunner
import com.android.server.wm.flicker.FlickerTestRunnerFactory
import com.android.server.wm.flicker.endRotation
@@ -32,7 +31,6 @@ import com.android.server.wm.flicker.helpers.StandardAppHelper
import com.android.server.wm.flicker.layerAlwaysVisible
import com.android.server.wm.flicker.helpers.WindowUtils
import com.android.server.wm.flicker.helpers.buildTestTag
-import com.android.server.wm.flicker.helpers.isRotated
import com.android.server.wm.flicker.navBarLayerIsAlwaysVisible
import com.android.server.wm.flicker.navBarLayerRotatesAndScales
import com.android.server.wm.flicker.navBarWindowIsAlwaysVisible
@@ -58,10 +56,8 @@ import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class SeamlessAppRotationTest(
- testName: String,
- flickerProvider: () -> Flicker,
- cleanUp: Boolean
-) : FlickerTestRunner(testName, flickerProvider, cleanUp) {
+ testSpec: FlickerTestRunnerFactory.TestSpec
+) : FlickerTestRunner(testSpec) {
companion object : RotationTransition(InstrumentationRegistry.getInstrumentation()) {
override val testApp: StandardAppHelper
get() = SeamlessRotationAppHelper(instrumentation)
@@ -70,6 +66,8 @@ class SeamlessAppRotationTest(
ActivityOptions.EXTRA_STARVE_UI_THREAD to configuration.starveUiThread.toString()
)
+ private val testFactory = FlickerTestRunnerFactory.getInstance()
+
private val Bundle.starveUiThread
get() = this.getBoolean(ActivityOptions.EXTRA_STARVE_UI_THREAD, false)
@@ -80,8 +78,8 @@ class SeamlessAppRotationTest(
}
@JvmStatic
- private fun FlickerTestRunnerFactory.getConfigurations(): List<Bundle> {
- return this.getConfigRotationTests().flatMap {
+ private fun getConfigurations(): List<Bundle> {
+ return testFactory.getConfigRotationTests().flatMap {
val defaultRun = it.createConfig(starveUiThread = false)
val busyUiRun = it.createConfig(starveUiThread = true)
listOf(defaultRun, busyUiRun)
@@ -91,8 +89,7 @@ class SeamlessAppRotationTest(
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<Array<Any>> {
- val factory = FlickerTestRunnerFactory(instrumentation, repetitions = 2)
- val configurations = factory.getConfigurations()
+ val configurations = getConfigurations()
val testSpec: FlickerBuilder.(Bundle) -> Unit = { configuration ->
withTestName {
val extra = if (configuration.starveUiThread) {
@@ -161,7 +158,8 @@ class SeamlessAppRotationTest(
}
}
- return factory.buildRotationTest(transition, testSpec, configurations)
+ return testFactory.buildRotationTest(instrumentation, transition, testSpec,
+ deviceConfigurations = configurations, repetitions = 2)
}
}
} \ No newline at end of file
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 104758de49f1..5381009fdf2b 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -98,6 +98,8 @@ public class PackageWatchdogTest {
private final TestClock mTestClock = new TestClock();
private TestLooper mTestLooper;
private Context mSpyContext;
+ // Keep track of all created watchdogs to apply device config changes
+ private List<PackageWatchdog> mAllocatedWatchdogs;
@Mock
private ConnectivityModuleConnector mConnectivityModuleConnector;
@Mock
@@ -112,7 +114,8 @@ public class PackageWatchdogTest {
MockitoAnnotations.initMocks(this);
new File(InstrumentationRegistry.getContext().getFilesDir(),
"package-watchdog.xml").delete();
- adoptShellPermissions(Manifest.permission.READ_DEVICE_CONFIG);
+ adoptShellPermissions(Manifest.permission.READ_DEVICE_CONFIG,
+ Manifest.permission.WRITE_DEVICE_CONFIG);
mTestLooper = new TestLooper();
mSpyContext = spy(InstrumentationRegistry.getContext());
when(mSpyContext.getPackageManager()).thenReturn(mMockPackageManager);
@@ -157,12 +160,23 @@ public class PackageWatchdogTest {
return storedValue == null ? defaultValue : Long.parseLong(storedValue);
}
).when(() -> SystemProperties.getLong(anyString(), anyLong()));
+
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
+ PackageWatchdog.PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED,
+ Boolean.toString(true), false);
+
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
+ PackageWatchdog.PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT,
+ Integer.toString(PackageWatchdog.DEFAULT_TRIGGER_FAILURE_COUNT), false);
+
+ mAllocatedWatchdogs = new ArrayList<>();
}
@After
public void tearDown() throws Exception {
dropShellPermissions();
mSession.finishMocking();
+ mAllocatedWatchdogs.clear();
}
@Test
@@ -611,10 +625,6 @@ public class PackageWatchdogTest {
*/
@Test
public void testExplicitHealthCheckStateChanges() throws Exception {
- adoptShellPermissions(
- Manifest.permission.WRITE_DEVICE_CONFIG,
- Manifest.permission.READ_DEVICE_CONFIG);
-
TestController controller = new TestController();
PackageWatchdog watchdog = createWatchdog(controller, true /* withPackagesReady */);
TestObserver observer = new TestObserver(OBSERVER_NAME_1,
@@ -807,9 +817,6 @@ public class PackageWatchdogTest {
/** Test default values are used when device property is invalid. */
@Test
public void testInvalidConfig_watchdogTriggerFailureCount() {
- adoptShellPermissions(
- Manifest.permission.WRITE_DEVICE_CONFIG,
- Manifest.permission.READ_DEVICE_CONFIG);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
PackageWatchdog.PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT,
Integer.toString(-1), /*makeDefault*/false);
@@ -835,9 +842,6 @@ public class PackageWatchdogTest {
/** Test default values are used when device property is invalid. */
@Test
public void testInvalidConfig_watchdogTriggerDurationMillis() {
- adoptShellPermissions(
- Manifest.permission.WRITE_DEVICE_CONFIG,
- Manifest.permission.READ_DEVICE_CONFIG);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
PackageWatchdog.PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT,
Integer.toString(2), /*makeDefault*/false);
@@ -850,7 +854,6 @@ public class PackageWatchdogTest {
watchdog.startObservingHealth(observer, Arrays.asList(APP_A, APP_B), Long.MAX_VALUE);
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
- mTestLooper.dispatchAll();
moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS + 1);
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
@@ -862,7 +865,6 @@ public class PackageWatchdogTest {
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
- mTestLooper.dispatchAll();
moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_TRIGGER_FAILURE_DURATION_MS - 1);
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
@@ -917,9 +919,6 @@ public class PackageWatchdogTest {
/** Test we are notified when enough failures are triggered within any window. */
@Test
public void testFailureTriggerWindow() {
- adoptShellPermissions(
- Manifest.permission.WRITE_DEVICE_CONFIG,
- Manifest.permission.READ_DEVICE_CONFIG);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
PackageWatchdog.PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT,
Integer.toString(3), /*makeDefault*/false);
@@ -933,11 +932,9 @@ public class PackageWatchdogTest {
// Raise 2 failures at t=0 and t=900 respectively
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
- mTestLooper.dispatchAll();
moveTimeForwardAndDispatch(900);
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
PackageWatchdog.FAILURE_REASON_UNKNOWN);
- mTestLooper.dispatchAll();
// Raise 2 failures at t=1100
moveTimeForwardAndDispatch(200);
@@ -1303,15 +1300,15 @@ public class PackageWatchdogTest {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
PackageWatchdog.PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED,
Boolean.toString(enabled), /*makeDefault*/false);
- //give time for DeviceConfig to broadcast the property value change
- try {
- Thread.sleep(SHORT_DURATION);
- } catch (InterruptedException e) {
- fail("Thread.sleep unexpectedly failed!");
+ // Call updateConfigs() so device config changes take effect immediately
+ for (PackageWatchdog watchdog : mAllocatedWatchdogs) {
+ watchdog.updateConfigs();
}
}
private void moveTimeForwardAndDispatch(long milliSeconds) {
+ // Exhaust all due runnables now which shouldn't be executed after time-leap
+ mTestLooper.dispatchAll();
mTestClock.moveTimeForward(milliSeconds);
mTestLooper.moveTimeForward(milliSeconds);
mTestLooper.dispatchAll();
@@ -1354,6 +1351,7 @@ public class PackageWatchdogTest {
verify(mConnectivityModuleConnector).registerHealthListener(
mConnectivityModuleCallbackCaptor.capture());
}
+ mAllocatedWatchdogs.add(watchdog);
return watchdog;
}
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index 0db2b2af7260..7b2a07fd80f8 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -1225,4 +1225,44 @@ public class RollbackTest {
InstallUtils.dropShellPermissionIdentity();
}
}
+
+ /**
+ * Tests an app can be rolled back to the previous signing key.
+ *
+ * <p>The rollback capability in the signing lineage allows an app to be updated to an APK
+ * signed with a previous signing key in the lineage; however this often defeats the purpose
+ * of key rotation as a compromised key could then be used to roll an app back to the previous
+ * key. To avoid requiring the rollback capability to support app rollbacks the PackageManager
+ * allows an app to be rolled back to the previous signing key if the rollback install reason
+ * is set.
+ */
+ @Test
+ public void testRollbackAfterKeyRotation() throws Exception {
+ try {
+ InstallUtils.adoptShellPermissionIdentity(
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.DELETE_PACKAGES,
+ Manifest.permission.TEST_MANAGE_ROLLBACKS,
+ Manifest.permission.MANAGE_ROLLBACKS);
+
+ // Uninstall TestApp.A
+ Uninstall.packages(TestApp.A);
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
+
+ // Install v1 of the app with the original signing key (without rollbacks enabled).
+ Install.single(TestApp.AOriginal1).commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+
+ // Upgrade from v1 to v2 with the rotated signing key, with rollbacks enabled.
+ Install.single(TestApp.ARotated2).setEnableRollback().commit();
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+
+ // Roll back the app.
+ RollbackInfo available = waitForAvailableRollback(TestApp.A);
+ RollbackUtils.rollback(available.getRollbackId());
+ assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+ } finally {
+ InstallUtils.dropShellPermissionIdentity();
+ }
+ }
}
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
index ef973acf763b..861d221238ff 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
@@ -182,6 +182,24 @@ public class UsbHandlerTest {
@SmallTest
@Test
+ public void setFunctionsNcmAndRndis() {
+ final long rndisPlusNcm = UsbManager.FUNCTION_RNDIS | UsbManager.FUNCTION_NCM;
+
+ mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS,
+ UsbManager.FUNCTION_NCM));
+ assertEquals(UsbManager.FUNCTION_NCM, mUsbHandler.getEnabledFunctions() & rndisPlusNcm);
+
+ mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS,
+ rndisPlusNcm));
+ assertEquals(rndisPlusNcm, mUsbHandler.getEnabledFunctions() & rndisPlusNcm);
+
+ mUsbHandler.handleMessage(mUsbHandler.obtainMessage(MSG_SET_CURRENT_FUNCTIONS,
+ UsbManager.FUNCTION_NCM));
+ assertEquals(UsbManager.FUNCTION_NCM, mUsbHandler.getEnabledFunctions() & rndisPlusNcm);
+ }
+
+ @SmallTest
+ @Test
public void enableAdb() {
sendBootCompleteMessages(mUsbHandler);
Message msg = mUsbHandler.obtainMessage(MSG_ENABLE_ADB);
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbManagerNoPermTest.java b/tests/UsbTests/src/com/android/server/usb/UsbManagerNoPermTest.java
index a0fd9d40506b..b8bd98ea3f21 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbManagerNoPermTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbManagerNoPermTest.java
@@ -16,6 +16,8 @@
package com.android.server.usb;
+import static org.junit.Assert.assertEquals;
+
import android.content.Context;
import android.hardware.usb.UsbManager;
@@ -23,12 +25,12 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.server.usblib.UsbManagerTestLib;
+
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
-import com.android.server.usblib.UsbManagerTestLib;
-
/**
* Unit tests for {@link android.hardware.usb.UsbManager}.
* Note: NOT claimed MANAGE_USB permission in Manifest
@@ -78,4 +80,35 @@ public class UsbManagerNoPermTest {
public void testUsbApi_SetCurrentFunctions_OnSecurityException() throws Exception {
mUsbManagerTestLib.testSetCurrentFunctionsEx(UsbManager.FUNCTION_NONE);
}
+
+ public void assertSettableFunctions(boolean settable, long functions) {
+ assertEquals(
+ "areSettableFunctions(" + UsbManager.usbFunctionsToString(functions) + "):",
+ settable, UsbManager.areSettableFunctions(functions));
+ }
+
+ /**
+ * Tests the behaviour of the static areSettableFunctions method. This method performs no IPCs
+ * and requires no permissions.
+ */
+ @Test
+ public void testUsbManager_AreSettableFunctions() {
+ // NONE is settable.
+ assertSettableFunctions(true, UsbManager.FUNCTION_NONE);
+
+ // MTP, PTP, RNDIS, MIDI, NCM are all settable by themselves.
+ assertSettableFunctions(true, UsbManager.FUNCTION_MTP);
+ assertSettableFunctions(true, UsbManager.FUNCTION_PTP);
+ assertSettableFunctions(true, UsbManager.FUNCTION_RNDIS);
+ assertSettableFunctions(true, UsbManager.FUNCTION_MIDI);
+ assertSettableFunctions(true, UsbManager.FUNCTION_NCM);
+
+ // Setting two functions at the same time is not allowed...
+ assertSettableFunctions(false, UsbManager.FUNCTION_MTP | UsbManager.FUNCTION_PTP);
+ assertSettableFunctions(false, UsbManager.FUNCTION_PTP | UsbManager.FUNCTION_RNDIS);
+ assertSettableFunctions(false, UsbManager.FUNCTION_MIDI | UsbManager.FUNCTION_NCM);
+
+ // ... except in the special case of RNDIS and NCM.
+ assertSettableFunctions(true, UsbManager.FUNCTION_RNDIS | UsbManager.FUNCTION_NCM);
+ }
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 14229c5d000f..bf73134952ee 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -380,6 +380,10 @@ public class ConnectivityServiceTest {
private QosCallbackMockHelper mQosCallbackMockHelper;
private QosCallbackTracker mQosCallbackTracker;
+ // State variables required to emulate NetworkPolicyManagerService behaviour.
+ private int mUidRules = RULE_NONE;
+ private boolean mRestrictBackground = false;
+
@Mock DeviceIdleInternal mDeviceIdleInternal;
@Mock INetworkManagementService mNetworkManagementService;
@Mock INetworkStatsService mStatsService;
@@ -1278,12 +1282,23 @@ public class ConnectivityServiceTest {
}
}
+ private void updateUidNetworkingBlocked() {
+ doAnswer(i -> NetworkPolicyManagerInternal.isUidNetworkingBlocked(
+ i.getArgument(0) /* uid */, mUidRules, i.getArgument(1) /* metered */,
+ mRestrictBackground)
+ ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean());
+ }
+
private void setUidRulesChanged(int uidRules) throws RemoteException {
- mPolicyListener.onUidRulesChanged(Process.myUid(), uidRules);
+ mUidRules = uidRules;
+ updateUidNetworkingBlocked();
+ mPolicyListener.onUidRulesChanged(Process.myUid(), mUidRules);
}
private void setRestrictBackgroundChanged(boolean restrictBackground) throws RemoteException {
- mPolicyListener.onRestrictBackgroundChanged(restrictBackground);
+ mRestrictBackground = restrictBackground;
+ updateUidNetworkingBlocked();
+ mPolicyListener.onRestrictBackgroundChanged(mRestrictBackground);
}
private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) {
@@ -6842,9 +6857,15 @@ public class ConnectivityServiceTest {
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(true);
cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
setUidRulesChanged(RULE_REJECT_ALL);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+ assertNull(mCm.getActiveNetwork());
+ assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
// ConnectivityService should cache it not to invoke the callback again.
setUidRulesChanged(RULE_REJECT_METERED);
@@ -6852,32 +6873,60 @@ public class ConnectivityServiceTest {
setUidRulesChanged(RULE_NONE);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
setUidRulesChanged(RULE_REJECT_METERED);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+ assertNull(mCm.getActiveNetwork());
+ assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
// Restrict the network based on UID rule and NOT_METERED capability change.
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+
mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
mCellNetworkAgent);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+ assertNull(mCm.getActiveNetwork());
+ assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+
setUidRulesChanged(RULE_ALLOW_METERED);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
setUidRulesChanged(RULE_NONE);
cellNetworkCallback.assertNoCallback();
- // Restrict the network based on BackgroundRestricted.
+ // Restrict background data. Networking is not blocked because the network is unmetered.
setRestrictBackgroundChanged(true);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+ assertNull(mCm.getActiveNetwork());
+ assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
+ assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
setRestrictBackgroundChanged(true);
cellNetworkCallback.assertNoCallback();
- setRestrictBackgroundChanged(false);
+
+ setUidRulesChanged(RULE_ALLOW_METERED);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+ assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+
+ setRestrictBackgroundChanged(false);
cellNetworkCallback.assertNoCallback();
+ assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
+ assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
mCm.unregisterNetworkCallback(cellNetworkCallback);
}
diff --git a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
index ef2653204af5..c64f4bc605f1 100644
--- a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
+++ b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
@@ -20,6 +20,7 @@ import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.app.AlarmManager;
@@ -948,8 +949,9 @@ public class WifiNl80211Manager {
* has been set up).
*/
public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType,
- @Nullable Set<Integer> freqs, @Nullable List<byte[]> hiddenNetworkSSIDs,
- @Nullable Bundle extraScanningParams) {
+ @SuppressLint("NullableCollection") @Nullable Set<Integer> freqs,
+ @SuppressLint("NullableCollection") @Nullable List<byte[]> hiddenNetworkSSIDs,
+ @SuppressLint("NullableCollection") @Nullable Bundle extraScanningParams) {
IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
if (scannerImpl == null) {
Log.e(TAG, "No valid wificond scanner interface handler for iface=" + ifaceName);